cdq分治入门学习 cogs 1752 Mokia nwerc 2015-2016 G 二维偏序
2017-10-23 21:40
525 查看
/* CDQ分治的对象是时间。 即对于一个时间段[L, R],我们取mid = (L + R) / 2。 分治的每层只考虑mid之前的修改对mid之后的查询的贡献,然后递归到[L,mid],(mid,R]。 显然,CDQ分治是一种离线算法,我们需要将所有的修改/查询存下来,一起进行操作。 同时,CDQ分治还需要满足:操作之间相互独立,即一个操作的存在不会影响到另一个操作的存在。 经典入门题 单点修改 矩形查询 如果此题矩形小一点的话 可以使用树状数组套线段树 但是矩形过大时就不适用了 这里可以将一个询问拆成四个前缀和查询,然后和修改操作一起 做cdq分治 */ #include<bits/stdc++.h> #define LL long long using namespace std; const int N = 2e6 + 1; int tr ,W; int lowbit(int x){return x & (-x);} void up(int pos,int v){ for(;pos <= W;pos += lowbit(pos)) tr[pos] += v; } int getsum(int pos){ int ans = 0; for(;pos;pos -= lowbit(pos)) ans += tr[pos]; return ans; } struct Q{ int x, y, type, q, v, order; Q(){}; Q(int x,int y,int type, int q,int v,int order):x(x),y(y),type(type),q(q),v(v),order(order){}; bool operator<(const Q&rhs)const{ return x < rhs.x; } }qr ,tmp ; int ans ; void cdq(int l,int r){ if(l == r) return ; int mid = l + r >> 1; int p1 = l,p2 = mid + 1; /// 首先将mid之前的操作 全部放到mid左边 mid之后的操作全部放到右边,保证了按时间分治,并且左右都是x递增的 for(int i = l;i <= r;i++){ if(qr[i].order <= mid) tmp[p1++] = qr[i]; else tmp[p2++] = qr[i]; } for(int i = l;i <= r;i++) qr[i] = tmp[i]; int j = l; ///计算完mid时间轴左边的修改对右边查询的贡献,恢复修改 for(int i = mid + 1;i <= r;i++){ if(qr[i].type == 2) { for(; j <= mid && qr[j].x <= qr[i].x; j++){ if(qr[j].type == 1) up(qr[j].y,qr[j].v); } ans[qr[i].q] += qr[i].v * getsum(qr[i].y); } } for(int i = l;i < j;i++) if(qr[i].type == 1) up(qr[i].y, -qr[i].v); ///进行递归分治 cdq(l, mid);cdq(mid + 1, r); } int main() { int op, a, b, c, d, id = 0, tot = 0; while(scanf("%d", &op) && op != 3){ if(op == 0) scanf("%d", &W); else if(op == 1){ scanf("%d%d%d", &a, &b, &c); qr[++id] = Q(a, b, 1, 0, c, id); } else{ ++tot; scanf("%d%d%d%d", &a, &b, &c, &d); qr[++id] = Q(a - 1, b - 1, 2, tot, 1, id); qr[++id] = Q(c, d, 2, tot, 1, id); qr[++id] = Q(a - 1, d, 2, tot, -1, id); qr[++id] = Q(c, b - 1, 2, tot, -1, id); } } sort(qr + 1, qr + id + 1); cdq(1, id); for(int i = 1; i <= tot; i++) printf("%d\n", ans[i]); return 0; }
http://codeforces.com/gym/101485/attachments 求出多少对(i,j) 满足i < j 且a[j] < a[i] 且 b[j] < b[i] 做法 第一维分治 第二维树状数组 时间复杂度为O(nlognlogn) 空间复杂度O(n) 解决二维偏序问题 其他做法可能空间复杂度为过高 #include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #include<vector> #include<map> #include<set> #include<queue> #define LL long long using namespace std; #define ms(dp,x) memset(dp,x,sizeof dp) const int N = 2e5 + 10; LL ans; int n; int tr ; int vis ; struct Q{ int id,a,b,c; Q(){}; }q ; int lowbit(int x){return x &(-x);} void up(int pos,int v){ for(;pos <= n;pos += lowbit(pos)) tr[pos] += v; } int getsum(int pos){ int ans = 0; for(;pos;pos -= lowbit(pos)) ans += tr[pos]; return ans; } bool cmpx(Q x,Q y){return x.b < y.b;} bool cmprx(Q x,Q y){return x.id < y.id;} void cdq(int l,int r){ if(l == r) return ; int mid = l + r >> 1; cdq(l,mid); sort(q + l,q + mid + 1, cmpx); sort(q + mid + 1,q + r + 1, cmpx); int i = l; LL tmp = 0; for(int j = mid + 1;j <= r;j++){ while(i <= mid && q[i].b < q[j].b) { up(q[i++].c,1); } tmp += getsum(q[j].c - 1); } ans += tmp; i = l; for(int j = mid + 1;j <= r;j++){ while(i <= mid && q[i].b < q[j].b) { up(q[i++].c,-1); } } sort(q + mid + 1,q + r + 1, cmprx); cdq(mid + 1,r); } int main() { int x; while(scanf("%d",&n)==1){ for(int i = 1;i <= n;i++) { scanf("%d",&q[i].a); vis[q[i].a] = i; q[i].id = i; } for(int i = 1;i <= n;i++) { scanf("%d",&x); q[vis[x]].b = i; } for(int i = 1;i <= n;i++) { scanf("%d",&x); q[vis[x]].c = i; } memset(tr, 0, sizeof tr); ans = 0; cdq(1,n); printf("%lld\n",ans); } return 0; } /* 8 1 4 8 3 5 7 2 6 6 4 8 3 5 2 7 1 6 4 8 3 5 2 7 1 */
相关文章推荐
- cogs1752[boi2007]mokia 摩基亚 (cdq分治)
- COGS1752 [BOI2007]摩基亚Mokia(CDQ分治 + 二维前缀和 + 线段树)
- COGS 577 蝗灾 [CDQ分治入门题]
- COGS 2479. [HZOI 2016]偏序 [CDQ分治套CDQ分治 四维偏序]
- cdq分治&整体二分学习缓存
- 【深度学习入门—2015MLDS】1. What is Machine Learning, Deep Learning and Structured Learning?
- Android新手入门2016(6)--客户端编程思想的初步思考和Android学习路线
- [BZOJ4553][HEOI2016]序列 CDQ分治
- 【深度学习入门—2015MLDS】2. Neural Network(Basic Ideas)
- 【cdq分治】cdq分治与整体二分学习笔记Part2.cdq分治
- bzoj4430 [Nwerc2015]Guessing Camels赌骆驼(CDQ分治)
- 【COGS】577 蝗灾 cdq分治
- [背包 压位 CDQ分治] ICPC 2016 Hong Kong H. Slim Cut
- 我的2015学习总结及2016的技术规划(2016.02)
- COGS1752. [BOI2007]摩基亚Mokia(CDQ,树状数组)
- CDQ分治学习笔记
- bzoj 4430: [Nwerc2015]Guessing Camels赌骆驼 (CDQ分治)
- 【HDU5730 2016 Multi-University Training Contest 1H】【FFT + cdq 分治】 Shell Necklace f[i]=∑f[i-j] x a[j]
- [学习笔记] CDQ分治 从感性理解到彻底晕菜
- [BZOJ3939][Usaco2015 Feb]Cow Hopscotch(cdq分治)