COGS 2580. [HZOI 2015]偏序 II (CDQ分治+BIT)
来源:互联网 发布:c语言打印long 编辑:程序博客网 时间:2024/06/05 05:24
题目传送门
COGS 2580. [HZOI 2015]偏序 II
Solution
由于周围的神犇们都学了CDQ分治,菜鸡我整天对他们的讨论一头雾水,于是我也照葫芦画瓢地学了一发,然后就找了一道CDQ分治裸题,来自我愉悦一下。
首先CDQ分治和整体二分有些相像,我个人的理解就是CDQ分治是注重过程的二分,整体二分则是直接二分答案,然后将操作划分。
CDQ一般的套路就是将一段可看成修改和询问操的作序列按时间排好序,去掉时间限制,然后划分为二成
对于n维偏序问题,编号已有序,层层CDQ下去,按不同的关键字排序,最后一层用跟求逆序对(即二维偏序)一样的方法,存进一个权值BIT中修改和查询。
三维坐标最长不降子序列和矩形动态区间和问题也可以用类似的手段解决。
不过这都基于一个大前提:题目支持离线操作。强制在线不能排序的话就只能树套树了。
言归正传,这题就是求五维偏序,明显离线,直接用CDQ套几下CDQ。
首先第一维的编号已经排好序了,都是左边影响右边了。处理左边,然后一起按
到第三层,处理左边对右边的影响就直接用BIT去做,BIT以第五维关键字做下标,是修改操作就Add,查询就Sum。做完记得像整体二分一样反向标记,清空BIT。
然后此果题就是这样做了,时间复杂度是
以上是一个初接触CDQ分治的蒟蒻的口胡,请各位神犇轻喷。。
Code
#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <iostream>#include <cmath>#define MAXN 50005using namespace std;int n, BIT[MAXN], ans, turn;struct Data{ int id, a, b, c, d; bool type;}op[5][MAXN];bool cmp(Data A, Data B){ if(turn == 1) return A.a < B.a; if(turn == 2) return A.b < B.b; return A.c < B.c; }int lowbit(int x){ return x & (-x);}void Add(int x, int v){ for(int i = x; i <= n; i += lowbit(i)) BIT[i] += v;}int Sum(int x){ int res = 0; for(int i = x; i > 0; i -= lowbit(i)) res += BIT[i]; return res;}int Work(int cnt){ int res = 0; for(int i = 1; i <= cnt; i++){ if(!op[3][i].type) Add(op[3][i].d, 1); else res += Sum(op[3][i].d); } for(int i = 1; i <= cnt; i++) if(!op[3][i].type) Add(op[3][i].d, -1); return res;}void CDQ(int now, int L, int R){ if(L == R) return; int mid = (L + R) >> 1, cnt = 0; CDQ(now, L, mid);//这里也可以放在处理右边的上一行 for(int i = L; i <= mid; i++){ if(now == 1) op[now][++cnt] = op[now-1][i], op[now][cnt].type = false; else if(!op[now-1][i].type) op[now][++cnt] = op[now-1][i]; } for(int i = mid+1; i <= R; i++){ if(now == 1) op[now][++cnt] = op[now-1][i], op[now][cnt].type = true; else if(op[now-1][i].type) op[now][++cnt] = op[now-1][i]; } if(cnt){ turn = now; sort(op[now]+1, op[now]+cnt+1, cmp); if(now == 3) ans += Work(cnt); else CDQ(now+1, 1, cnt); } CDQ(now, mid+1, R);}int main(){ freopen("partial_order_two.in", "r", stdin); freopen("partial_order_two.out", "w", stdout); scanf("%d", &n); for(int i = 1; i <= n; i++) scanf("%d", &op[0][i].a); for(int i = 1; i <= n; i++) scanf("%d", &op[0][i].b); for(int i = 1; i <= n; i++) scanf("%d", &op[0][i].c); for(int i = 1; i <= n; i++) scanf("%d", &op[0][i].d); for(int i = 1; i <= n; i++) op[0][i].id = i; CDQ(1, 1, n); printf("%d\n", ans); return 0;}
最美丽的谎言,将你带到了我的身边。
- COGS 2580. [HZOI 2015]偏序 II (CDQ分治+BIT)
- COGS 2580. [HZOI 2015]偏序 II
- COGS 2479. [HZOI 2016]偏序 双重CDQ分治+树状数组
- COGS2580:[HZOI 2015]偏序 II (三层CDQ分治+树状数组)
- 【COGS】577 蝗灾 cdq分治
- COGS 577 蝗灾 cdq分治+树状数组
- COGS 577 蝗灾 线段树+CDQ分治
- cogs [BOI2007]摩基亚Mokia CDQ 分治
- COGS 2123. [HZOI 2015] Glass Beads
- UVA 11990 bit + cdq 分治
- 【COGS】1752. [BOI2007]摩基亚Mokia cdq分治模板题
- cogs 1752 [BOI2007]摩基亚Mokia(cdq分治+树状数组)
- COGS 2294. [HZOI 2015] 释迦 (FFT mod any prime)
- COGS-2282 [HZOI 2015]黑树白(树状数组+树链剖分)
- [BZOJ1176][Balkan2007]Mokia(cdq分治+bit)
- [BZOJ3262]陌上花开(cdq分治+bit)
- [BZOJ3262]陌上花开(cdq分治+bit)
- 【BZOJ3295】动态逆序对,CDQ分治/BIT套权值线段树
- lnmp环境 laravel5.2 框架上线后报404
- idea14 如何创建传统的web项目 ,添加jar文件
- Windows上Python2和3如何兼容
- 数据结构-链表,队列,栈
- 蓝牙4.0BLE抓包(一)
- COGS 2580. [HZOI 2015]偏序 II (CDQ分治+BIT)
- 基于Kinect体感遥控多功能小车
- solr 相似匹配
- 【theano-windows】学习笔记四——theano中的条件语句
- linux下 多线程的使用
- 30 个很棒的 PHP 开源 CMS 内容管理系统
- Maven缺少JDK 编译插件报错 --- DescriptionResourcePathLocation Type
- oracle中一个表update慢的优化
- 安全发布和安全初始化