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