開始學cdq分治,然後看到了__stdcall的部落格,然後發現從前打過的歸併排序求逆序對就是乙個典型的cdq分治。
大致思想就是先按照一維來排序,然後按照第一維的順序進行分治。然後在分治的過程中保證在第一維下左半部分永遠小於右半部分,然後就利用這個性質在左半邊右半邊分別按照第二維度排序,由於左邊和右邊都是處理好了的,所以只需要處理左邊對於右邊的貢獻,前面既保證了第一位有序,又保證了第二維有序,所以時間的複雜度在每一層分治上面都是線性的。
理解了一下之後再看樹狀陣列的模板發現每乙個操作可以表示為乙個二元組(a
,b) (a,
b)
,a a
表示時間,
b' role="presentation">b
b表示位置,我們所求的就是對於每乙個詢問操作,時間序在它之前並且位置在它之前的修改操作的和,基本上打法就和歸併一樣。
/*********************==
* author : ylsoi
* problem : luogu3374
* algorithm : cdq
* time : 2018.7.29
* ***************====*/
#include
#define rep(i,a,b) for(int i=a;i<=b;++i)
typedef long long ll;
using namespace std;
void file()
const int maxn=5e5+10;
int n,m,a[maxn],sum[maxn],tot;
struct nodeb[maxn<<1],tmp[maxn<<1];
bool cmp(node xx,node yy)
#define mid ((l+r)>>1)
void cdq(int l,int r)
else
}while(pl<=mid)tmp[p++]=b[pl++];
while(pr<=r)
rep(i,l,r)b[i]=tmp[i];
}int main()
rep(i,1,m);
else;
b[++tot]=(node);}}
cdq(1,tot);
sort(b+1,b+tot+1,cmp);
rep(i,1,tot)
}return
0;}
bzoj 3262(cdq分治 樹狀陣列)
正經題解在後面 斜體字都是一年前在沒有把cdq扯清楚的情況下應付的,即使現在真正理解了cdq,還是將這堆話留在這,畢竟,花無重開日,人無再少年 runid user problem result memory time language code length submit time 2374693...
bzoj 1176 cdq分治套樹狀陣列
題面 維護乙個w w的矩陣,初始值均為s.每次操作可以增加某格仔的權值,或詢問某子矩陣的總權值.修改運算元m 160000,詢問數q 10000,w 2000000.input 第一行兩個整數,s,w 其中s為矩陣初始值 w為矩陣大小 接下來每行為一下三種輸入之一 不包含引號 1 x y a 2 x...
bzoj 2683 簡單題 cdq分治 樹狀陣列
要求資瓷下列操作 1 x y z把 x,y 加上z 2 x1 y1 x2 y2求矩形x1 y1 x2 y2的權值和 n 500000,x,y n,q 200000 首先可以把乙個詢問用容斥原理拆成四個詢問,然後在cdq分治中二分乙個橫座標mid,然後把操作從前往後掃一遍,若是修改操作且橫座標不大於m...