日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

CDQ 分治算法模板

發(fā)布時間:2025/3/15 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CDQ 分治算法模板 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

CDQ分治

1.三維偏序問題:三維偏序(陌上花開)

#include<bits/stdc++.h> #define RG register #define IL inline #define _ 200005 using namespace std; IL int gi(){RG int data = 0 , m = 1; RG char ch = 0;while(ch != '-' && (ch<'0'||ch>'9'))ch = getchar();if(ch == '-'){m = -1; ch = getchar();}while('0'<=ch && ch<='9')data = (data<<3) + (data<<1) + (ch - '0') , ch = getchar();return (m) ? data : -data; }int tot,bt[_],n,k,f[_],g[_],blg[_]; long long ans[_];struct Node{int a, b, c , w , id;//w記錄這個節(jié)點(diǎn)對應(yīng)多少個真實(shí)節(jié)點(diǎn),id則是其對應(yīng)編號.bool operator <(const Node &B)const{return (b == B.b) ? c <= B.c : b < B.b;} }; Node q1[_],q[_],tmp[_];namespace BIT{IL void Update(RG int ps,RG int dt){for(RG int i = ps; i <= k; i += (i&-i))bt[i] += dt;}IL void Clear(RG int ps){for(RG int i = ps; i <= k; i += (i&-i))bt[i] = 0;}IL int Query(RG int ps){RG int res = 0;for(RG int i = ps; i > 0; i -= (i&-i))res += bt[i];return res;} }void cdq(RG int L,RG int R){if(L == R)return;RG int mid = (L+R)>>1; cdq(L,mid); cdq(mid+1,R);RG int l = L , r = mid+1 , oo = L-1;while(l <= mid && r <= R){if(q[l] < q[r])BIT::Update(q[l].c,q[l].w) ,tmp[++oo] = q[l++];elseg[q[r].id] += BIT::Query(q[r].c) ,tmp[++oo] = q[r++];}while(l <= mid)tmp[++oo] = q[l++];while(r <= R)g[q[r].id] += BIT::Query(q[r].c) ,tmp[++oo] = q[r++];for(RG int i = L; i <= R; i ++)BIT::Clear(tmp[i].c) , q[i] = tmp[i];return; }IL bool cmp(Node a,Node b){if(a.a != b.a)return a.a < b.a;if(a.b != b.b)return a.b < b.b;if(a.c != b.c)return a.c < b.c;return a.id < b.id; //注意:這里一定要隨便定義一個優(yōu)先級 } IL bool Equl(int nw,int cp){if(!cp)return false;else return (q1[nw].a==q[cp].a &&q1[nw].b==q[cp].b && q1[nw].c==q[cp].c); }int main(){n = gi(); k = gi();for(RG int i = 1,a,b,c; i <= n; i ++)a = gi(),b = gi(),c = gi(),q1[i] = (Node){a , b , c , 1 , i};//去重:tot = 0;sort(q1+1,q1+n+1,cmp);for(RG int i = 1; i <= n; i ++){if(!Equl(i,tot))q[++tot] = q1[i] , q[tot].w = 1 , q[tot].id = tot;else q[tot].w ++;blg[i] = tot; //記錄i點(diǎn)是對應(yīng)去重后的哪個節(jié)點(diǎn)}cdq(1,tot);// f[i] 表示去重前點(diǎn)i滿足 (aj<=ai,bj<=bi,cj<=ci) 的j的個數(shù).// g[i] 表示去重后點(diǎn)i滿足條件的j的個數(shù)for(RG int i = 1; i <= tot; i ++)g[q[i].id] += q[i].w-1;for(RG int i = 1; i <= n; i ++)f[i] = g[blg[i]];for(RG int i = 1; i <= n; i ++)ans[f[i]] ++;for(RG int i = 0; i < n; i ++)printf("%lld\n",ans[i]);return 0; }

離線修改與查詢問題:樹狀數(shù)組 1

#include<bits/stdc++.h> #define RG register #define IL inline #define ll long long #define _ 4*500005 using namespace std;int n,m,ask,tot; ll ans[_];struct Do{int typ,pos,val;bool operator <(const Do &B)const{return (pos == B.pos)?typ < B.typ : pos < B.pos; } }; Do q[_],tmp[_];void cdq(RG int L,RG int R){if(L == R)return;RG int mid = (L+R)>>1; cdq(L,mid); cdq(mid+1,R);RG ll upt = 0 , l = L , r = mid+1 , oo = 0;while(l <= mid && r <= R){if(q[l] < q[r]){if(q[l].typ == 1)upt += q[l].val;tmp[++oo] = q[l++];}else {if(q[r].typ == 2)ans[q[r].val] -= upt;if(q[r].typ == 3)ans[q[r].val] += upt;tmp[++oo] = q[r++];}}while(l <= mid){if(q[l].typ == 1)upt += q[l].val;tmp[++oo] = q[l++];}while(r <= R){if(q[r].typ == 2)ans[q[r].val] -= upt;if(q[r].typ == 3)ans[q[r].val] += upt;tmp[++oo] = q[r++];}for(RG int i = L; i <= R; i ++)q[i] = tmp[i-L+1]; }int main(){scanf("%d %d",&n,&m);for(RG int i = 1,ww; i <= n; i ++)scanf("%d",&ww), q[++tot] = (Do){1,i,ww};ask = 0;for(RG int i = 1,tp,ps,ww; i <= m; i ++){scanf("%d %d %d",&tp,&ps,&ww);if(tp == 1)q[++tot] = (Do){1,ps,ww};elseq[++tot] = (Do){2,ps-1,++ask} ,q[++tot] = (Do){3,ww,ask};}cdq(1,tot);for(RG int i = 1; i <= ask; i ++)cout<<ans[i]<<endl;return 0; }

轉(zhuǎn)載于:https://www.cnblogs.com/Guess2/p/8367160.html

總結(jié)

以上是生活随笔為你收集整理的CDQ 分治算法模板的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。