hdu 5126 stars cdq分治
来源:互联网 发布:软件代理商名录 编辑:程序博客网 时间:2024/05/24 06:16
stars
Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 282 Accepted Submission(s): 68
The first line contains an integer
Next Q lines contain some integers, first input an integer
2111 1 1 12 1 1 1 1 1 11 2 2 21 1 1 22 1 1 1 2 2 21 3 3 31 4 4 41 5 5 51 6 6 62 1 1 1 6 6 62 3 3 3 6 6 6111 1 1 12 1 1 1 1 1 11 2 2 21 1 1 22 1 1 1 2 2 21 3 3 31 4 4 41 5 5 51 6 6 62 1 1 1 6 6 62 3 3 3 6 6 6
13741374
用kd树做超时了。网上看到是cdq分治的,看了下ppt。
http://wenku.baidu.com/link?url=VwuZ4ij8GABr5FOVcuU2yyMelwPSa_sXahA9lgVu0bQTrF2J3GuZGgHXE7LinI0-EulsxJJXZ3oMFL4dlIvOZdDlrIudCptcpawthnAMlj3
还看了下别人的解法
最后我的做法大致是这样的,但是比较慢
把一个询问拆成8个查询(容斥咯),用树状数组维护坐标z从0到需要查询位置点的个数,当然z要先离散化。
然后就是用cdq分治,使得每次查询都是有效点了。
思想就是划分一个个集合,使得每个集合里插入点在已经被处理的维度上,坐标都小于询问的坐标值
1. 因为插入和查询的点是有顺序的,所以其实应该看成是四维的。第一次应该先按操作的次序排序(其实就是不用排序了)做cdq分治
2.在cdq分治的第一次里,分治使得点按x轴排序,因为按左右两个部分,可以知道左边部分的次序<右边部分的操作次序,那么把左边的插入和右边的查询放到一起,那么新的集合里在次序这个维度上,查询的就高于插入的了。又因为分治按x排序,那么就可以线性的把新的集合按照x轴大小为第一关键字,次序为第二关键字的方式排序
3.在新的集合里,对y轴进行排序,因为左边的插入操作的点x<右边操作的x,那么满足左边插入的点的y小于右边当前查询的点y,那么在更新树状数组中左边插入点z处值,然后更新查询即可,由于树状数组每次要清空,所以插入的点都需要删除
对于树状数组的清空操作有两种方式:
1. 时间戳标记,用T[],tag,如果T[]=tag说明这个位置的值是新的,否则置成0,让T[]=tag,每次要清空的时候tag++即可
2.删除插入的点
#include<cstdio>#include<algorithm>using namespace std;struct Node{ int x,y,z,p,t; Node(){} Node(int x,int y,int z,int p,int t):x(x),y(y),z(z),p(p),t(t){}};#define maxn 450007Node star[maxn];Node star2[maxn];Node star3[maxn];int tree[maxn];int lowbit(int i){ return i&(-i);}void add(int i,int x){ while(i<maxn){ tree[i]+=x; i+=lowbit(i); }}int get(int i){ int ans = 0; while(i>0){ ans += tree[i]; i -= lowbit(i); } return ans;}int res[maxn];void CDQ2(int l,int r){ if(l == r) return ; int mid = (l+r)/2; CDQ2(l,mid); CDQ2(mid+1,r); int l1 =l, r1 = mid+1; while(r1 <= r){ while(l1 <= mid && star2[l1].y <= star2[r1].y){ if(star2[l1].t == 0) add(star2[l1].z,1); l1++; } if(star2[r1].t != 0){ res[star2[r1].p] += get(star2[r1].z)*star2[r1].t; } r1++; } while(l1 > l){ --l1; if(star2[l1].t == 0) add(star2[l1].z,-1); } l1 = l, r1 = mid+1; for(int i = l;i <= r; i++){ if((l1 <= mid && star2[l1].y <= star2[r1].y) || r1 > r ) star3[i] = star2[l1++]; else star3[i] = star2[r1++]; } for(int i = l; i <= r; i++) star2[i] = star3[i];}void CDQ1(int l,int r){ if(l == r) return ; int mid = (l+r)/2; CDQ1(l,mid); CDQ1(mid+1,r); int l1 = l, r1 = mid+1,n = 0; while(r1 <= r){ while(star[l1].t != 0 && l1 <= mid) l1++; while(star[r1].t == 0 && r1 <= r) r1++; if(r1 > r) break; if((star[l1].x <= star[r1].x && l1 <= mid)|| r1 > r) star2[n++] = star[l1++]; else star2[n++] = star[r1++]; } if(n > 0) CDQ2(0,n-1); l1 = l, r1 = mid+1; for(int i = l;i <= r; i++){ if((star[l1].x <= star[r1].x && l1 <= mid)|| r1 > r) star3[i] = star[l1++]; else star3[i] = star[r1++]; } for(int i = l;i <= r; i++) star[i] = star3[i];}int compn(Node a,Node b){ return a.p < b.p;}int compz(Node a,Node b){ return a.z < b.z;}int main(){ int t,q,a,x1,y1,z1,x2,y2,z2; scanf("%d",&t); while(t--){ int n = 0; scanf("%d",&q); while(q--){ scanf("%d",&a); if(a == 1){ scanf("%d%d%d",&x1,&y1,&z1); star[n++] = Node(x1,y1,z1,n,0); } else { scanf("%d%d%d%d%d%d",&x1,&y1,&z1,&x2,&y2,&z2); star[n++] = Node(x2,y2,z2,n,1); star[n++] = Node(x2,y1-1,z2,n,-1); star[n++] = Node(x1-1,y2,z2,n,-1); star[n++] = Node(x2,y2,z1-1,n,-1); star[n++] = Node(x1-1,y1-1,z2,n,1); star[n++] = Node(x1-1,y2,z1-1,n,1); star[n++] = Node(x2,y1-1,z1-1,n,1); star[n++] = Node(x1-1,y1-1,z1-1,n,-1); } } for(int i = 0;i < n; i++) res[i] = 0; sort(star,star+n,compz); a = 1; star[n].z = -1; for(int i = 0;i < n; i++){ if(star[i].z != star[i+1].z) star[i].z = a++; else star[i].z = a; } sort(star,star+n,compn); CDQ1(0,n-1); sort(star,star+n,compn); for(int i = 0;i < n; i++){ if(star[i].t != 0){ int ans = 0; for(int j = 0;j < 8; j++) ans += res[i+j]; printf("%d\n",ans); i += 7; } } } return 0;}
- hdu 5126 stars cdq分治
- Hdu-5126 stars(cdq分治)
- hdu 5126 stars(三维空间cdq分治)
- HDU 5126 stars cdq分治+树状数组
- hdu 5126 stars ( CDQ分治 + 树状数组)
- HDU 5126 stars (CDQ分治)
- 【HDU】5126 stars cdq分治套cdq分治套树状数组
- HDU 4456 CDQ分治
- HDU-5324 cdq分治
- HDU - 1166 CDQ分治
- Hdu 5618 CDQ分治
- HDU 4456 Crowd (cdq分治)
- hdu 5324 树套树、cdq分治
- HDU 5730 (CDQ分治 FFT)
- HDU 5552 (CDQ分治 NTT)
- HDU 5896 (CDQ分治 NTT)
- HDU 5552 CDQ分治+NTT
- HDU 5896 CDQ分治+NTT
- POJ 3278 Catch That Cow
- 浏览器停止支持SHA-1算法,我国用户如何应对?
- 数据库语言划分
- 机房重构中遇到的问题
- 《算法导论》笔记(11) 摊还分析 部分习题
- hdu 5126 stars cdq分治
- ViewPager实现TabHost动态添加、删除Fragment,用红色小圆球指示当前页面
- JDBC : Java获取数据库连接(Driver And DriverManager)
- NuGet 的基本语法
- IO-04. 混合类型数据格式化输入(5)
- Mysql 事务处理
- TRACE宏的功能
- SpringMVC数据验证
- iOS摄像头和相册-UIImagePickerController