CDQ分治小結

2022-04-05 20:33:46 字數 2281 閱讀 3268

一道cdq分治的比較模板又不是模板的問題.

設\(f_i\)表示\(a_j<=a_i\)且\(b_j<=b_i\)且\(c_j<=c_i\)的\(j\)的數量

對於\(d\in[0,n)\)讓你求\(f(i) == d\)的數量

其實個人感覺模板的話

還是嚴格小於比較好做

先來考慮一下嚴格小於該怎麼做

我們先對整體按照\(a_i\)排序,這樣的話我們進行的分治就滿足了第乙個限制

之後我們試想一下,如果要求左區間對於右區間的貢獻

我們只需要將兩邊分別排序

雖然這樣兩邊就不一定在滿足\(a_i\)的限制,但是左右兩個區間依舊滿足(因為我們是分別排序)

直接用權值樹狀陣列計算右邊對與左邊的貢獻

但是,如果要求小於等於,就要考慮有兩個值其\(a_i,b_i,c_i\)均相同的情況

這樣的話我們就去重

將重複\(n\)個的元素的權值改為\(n\)

最後\(cnt_+=ai.ans\)

即可

#include#include#include#include#include#include#includeusing namespace std;

const int n = 1e5 + 3;

const int m = 2e5 + 3;

int n,k;

struct bit

inline void ins(int x,int v)

inline int query(int x)

}t;struct nodea[n],b[n];

int cnt[n];

inline int read()

while(isdigit(ch))

return v * c;

}inline bool cmpx(node xx,node yy)

inline bool cmpy(node xx,node yy)

inline void solve(int l,int r)

for(int i = l;i < top;++i) t.ins(a[i].z,-a[i].val);

}int main()

swap(num,n);//for(int i = 1;i <= n;++i) printf("%d %d %d %d\n",a[i].x,a[i].y,a[i].z,a[i].val);

solve(1,n);

// for(int i = 1;i <= n;++i) printf("%d ",a[i].ans);puts("");

for(int i = 1;i <= n;++i) cnt[a[i].ans + a[i].val - 1] += a[i].val;

for(int i = 0;i < num;++i) printf("%d\n",cnt[i]);

return 0;

}

cdq的板子題了

我們以輸入的操作順序為第一維

操作的時間為第二維

第三維就直接查詢有多少數等於他就好了

但是由於排序是將

sort(a + l,a + mid + 1,cmp)
寫成了

sort(a + l + 1,a + mid + 1,cmp)
然後,調了一下午,還去找\(wqy\)學長丟人

#include#include#include#include#include#include#define ll long long

using namespace std;

const int n = 1e5 + 3;

int n;

struct qa[n];

map m;

inline ll read()

while(isdigit(ch))

return v * c;

}inline bool cmp(q x,q y)

inline bool cmp2(q x,q y)

inline void solve(int l,int r)

a[i].ans += m[a[i].val];

} m.clear();

}int main()

solve(1,n);

sort(a + 1,a + n + 1,cmp2);

for(int i = 1;i <= n;++i) if(a[i].type == 3) printf("%d\n",a[i].ans);

return 0;

cdq分治小結

一般的分治,眾所周知的,是通過將大的問題拆小,然後對小問題的答案進行合併得到大問題的答案,但是cdq分治不是。我們知道,分治時,將乙個區間從中間斬開,分兩半處理,cdq分治在處理完之後,不是合併答案,而是計算左區間對右區間的貢獻,這樣子可以將維度降低,問題就更好做了。現在有 n nn 個二元組,每個...

cdq分治學習小結

一臉懵逼的學了好久,應該算學會了吧。基本了解cdq分治的思想,然而 一如既往的醜。cdq分治只支援離線操作,主要作用是降維,反正就是大大優化了時間和空間。感覺不扯幾句作用非常不好 輸入長度為n的序列,並進行m次操作,操作分兩種 1.將編號為的數加上y 1 x y 2.求出某區間每乙個數的和 2 x ...

CDQ分治概述

log l og 的時間把它變成離線問題。正好有些題目的離線問題是比較簡單的。具體是什麼意思呢?我們對於每一層分治,只考慮前一半對於後一半的影響,然後在每個詢問當中記錄下來影響。最後把所有影響合併就可以得到每乙個詢問的答案。舉個例子 區間修改區間查詢。首先,在時間軸上離線分治。每一層分治後把詢問和查...