HDU5126 stars


Problem Description

John loves to see the sky. A day has Q times. Each time John will find a new star in the sky, or he wants to know how many stars between (x1,y1,z1) and (x2,y2,z2).

Input

The first line contains a single integer T(1≤T≤10) (the data for Q>100 less than 6 cases),, indicating the number of test cases.

The first line contains an integer Q(1≤Q≤50000),indicating how many times in a day.

Next Q lines contain some integers, first input an integer A(1≤A≤2).If A=1 then input 3 integers x, y and z, indicating a coordinate of one star.. If A=2 then input 6 integers x1,y1,z1,x2,y2,z2(1≤x,y,z,x1,y1,z1,x2,y2,z2≤109,x1≤x2,y1≤y2,z1≤z2).

Output

For each “A=2”,output an integer means how many stars in such a section.

Sample Input

2

11

1 1 1 1

2 1 1 1 1 1 1

1 2 2 2

1 1 1 2

2 1 1 1 2 2 2

1 3 3 3

1 4 4 4

1 5 5 5

1 6 6 6

2 1 1 1 6 6 6

2 3 3 3 6 6 6

11

1 1 1 1

2 1 1 1 1 1 1

1 2 2 2

1 1 1 2

2 1 1 1 2 2 2

1 3 3 3

1 4 4 4

1 5 5 5

1 6 6 6

2 1 1 1 6 6 6

2 3 3 3 6 6 6

Sample Output

1

3

7

4

1

3

7

4


题意就是问你在给定的三维空间里有多少个点

CDQ分治

先把一个三维空间差分成8个节点到(0,0)的三维空间,然后进行维护

首先CDQ分治掉时间这个维度

然后再分治掉x坐标这个维度,把左区间的修改和右区间的查询提出来进行处理

剩下的就变成一个简单的二维偏序,分治一下y就可以了

简单来说就是CDQ套CDQ


/*HDU5126 CDQ分治*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
#define N 500010
struct BIT{
int t[N];
void add(int x,int vl){for(;x<N;x+=x&(-x))t[x]+=vl;}
int query(int x){int ans=0;for(;x;x-=x&(-x))ans+=t[x];return ans;}
}T;
struct Que{
int x,y,z,id,typ,w;
Que(){}
Que(int _x,int _y,int _z,int _id,int _typ,int _w){
x=_x,y=_y,z=_z,id=_id,typ=_typ,w=_w;
}
}q1[N<<3],q2[N<<3],q3[N<<3],q4[N<<3];
int n,t,pre[N<<1],ans[N];
vector<int> v;
bool cmp1(Que a,Que b){
if(a.x!=b.x)return a.x<b.x;
return a.id<b.id;
}
bool cmp2(Que a,Que b){
if(a.y!=b.y)return a.y<b.y;
return a.id<b.id;
}
void solve2(int l,int r){
if(l>=r)return;
int mid=(l+r)>>1;
solve2(l,mid);
solve2(mid+1,r);
int lenl=0,lenr=0;
for(int i=l;i<=mid;i++)if(!q2[i].typ)q3[++lenl]=q2[i];
for(int i=mid+1;i<=r;i++)if(q2[i].typ)q4[++lenr]=q2[i];
sort(q3+1,q3+lenl+1,cmp2);
sort(q4+1,q4+lenr+1,cmp2);
int tl=1,tr=1;
while(tr<=lenr){
while(tl<=lenl&&q3[tl].y<=q4[tr].y)T.add(q3[tl].z,1),tl++;
ans[q4[tr].id]+=q4[tr].w*T.query(q4[tr].z);
tr++;
}
for(int i=1;i<tl;i++)T.add(q3[i].z,-1);
}
void solve1(int l,int r){//消除x维的影响
if(l>=r)return;
int mid=(l+r)>>1;
solve1(l,mid);
solve1(mid+1,r);
int newq=0;
for(int i=l;i<=mid;i++)if(!q1[i].typ)q2[++newq]=q1[i];
for(int i=mid+1;i<=r;i++)if(q1[i].typ)q2[++newq]=q1[i];
sort(q2+1,q2+newq+1,cmp1);
solve2(1,newq);
}
int main(){
//freopen("hdu5126.in","r",stdin);
scanf("%d",&t);
while(t--){
v.clear();
scanf("%d",&n);
int cnt=0,tot=0;
memset(ans,0,sizeof(ans));
for(int i=1;i<=n;i++){
int op;scanf("%d",&op);
if(op==1){
cnt++;
scanf("%d%d%d",&q1[cnt].x,&q1[cnt].y,&q1[cnt].z);
q1[cnt].id=i;q1[cnt].typ=0;
pre[++tot]=q1[cnt].z;
}else{
int x1,y1,z1,x2,y2,z2;
scanf("%d%d%d",&x1,&y1,&z1);
scanf("%d%d%d",&x2,&y2,&z2);
pre[++tot]=z1-1;
pre[++tot]=z2;
q1[++cnt]=Que(x2,y2,z2,i,1,1);
q1[++cnt]=Que(x1-1,y2,z2,i,1,-1);
q1[++cnt]=Que(x2,y1-1,z2,i,1,-1);
q1[++cnt]=Que(x2,y2,z1-1,i,1,-1);
q1[++cnt]=Que(x1-1,y1-1,z2,i,1,1);
q1[++cnt]=Que(x1-1,y2,z1-1,i,1,1);
q1[++cnt]=Que(x2,y1-1,z1-1,i,1,1);
q1[++cnt]=Que(x1-1,y1-1,z1-1,i,1,-1);
v.push_back(i);
}
}
sort(pre+1,pre+tot+1);
tot=unique(pre+1,pre+tot+1)-pre-1;
for(int i=1;i<=cnt;i++)q1[i].z=lower_bound(pre+1,pre+tot+1,q1[i].z)-pre;
solve1(1,cnt);//***cnt!=n
for(int i=0;i<v.size();i++)printf("%d\n",ans[v[i]]);
}
return 0;
}

HDU5126 stars【CDQ分治】*的更多相关文章

  1. HDU5126 stars(CDQ分治)

    传送门 大意: 向三维空间中加点,询问一个三维区间中点的个数. 解题思路: 带修改CDQ,将修改和询问一起插入CDQ分治询问. (询问可以由8个前缀和加减操作实现) 其中第一层CDQ维护x有序. 第二 ...

  2. hdu 5126 stars cdq分治套cdq分治+树状数组

    题目链接 给n个操作, 第一种是在x, y, z这个点+1. 第二种询问(x1, y1, z1). (x2, y2, z2)之间的总值. 用一次cdq分治可以将三维变两维, 两次的话就变成一维了, 然 ...

  3. HDU - 5126 stars (CDQ分治)

    题目链接 题目大意:一共有Q(1<=Q<=50000)组操作,操作分为两种: 1.在x,y,z处添加一颗星星 2.询问以(x1,y1,z1)与(x2,y2,z2)为左上和右下顶点的矩形之间 ...

  4. [学习笔记]CDQ分治和整体二分

    序言 \(CDQ\) 分治和整体二分都是基于分治的思想,把复杂的问题拆分成许多可以简单求的解子问题.但是这两种算法必须离线处理,不能解决一些强制在线的题目.不过如果题目允许离线的话,这两种算法能把在线 ...

  5. CDQ分治笔记

    以前一直不会CDQ……然后经常听到dalao们说“这题直接CDQ啊”“CDQ不就秒了吗”的时候我只能瑟瑟发抖QAQ CDQ分治 其实CDQ分治就是二分分治,每次将$[l,r]$的问题划分为$[l,mi ...

  6. CDQ分治--用时间降维的美丽算法

    CDQ分治–用时间降维的美丽算法 CDQ分治,网上的阐述很多,太专业性的文字我就不赘述,这里指谈谈自己的感受 还是%一下CDQ大神的论文 CDQ分治的主要想法就是降维(比如三维问题降维到二维问题),并 ...

  7. CDQ分治的嵌套

    CDQ的嵌套 上一篇博客介绍了一下CDQ的入门思想.这里再介绍一下它的进阶,CDQ套CDQ.其实如果对入门思想掌握的透彻,嵌套也是很容易掌握的,思想是一样的. 什么是嵌套 简单地说,有的问题,如果用一 ...

  8. CDQ分治&整体二分学习个人小结

    目录 小结 CDQ分治 二维LIS 第一道裸题 bzoj1176 Mokia bzoj3262 陌上花开 bzoj 1790 矩形藏宝地 hdu5126四维偏序 P3157 [CQOI2011]动态逆 ...

  9. 技巧专题3(cdq分治、整体二分等)

    cdq分治与整体二分 cdq来源于2008年国家集训队作业陈丹琦(雅礼巨佬),用一个log的代价完成从静态到动态(很多时候是减少时间那一维的). 对于一个时间段[L, R],我们取mid = (L + ...

随机推荐

  1. MapReduce 应用实例

    Hadoop 版本2.8.0 前期准备工作: 1. 设置用户环境变量 PATH 和 CLASSPATH 方便执行 Hadoop 命令时不用转移到对应的目录下,shell 除了会在当前目录下还会到 PA ...

  2. Vuex访问状态对象的方法

    除了<Vuex最基本样例>中的方法外,还有两种方法访问状态对象state: 只需要改app.vue文件 方法一:引入computed <template> <div id ...

  3. UOJ34 多项式乘法(NTT)

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

  4. angularjs1 自定义图片查看器(可旋转、放大、缩小、拖拽)

    笔记: angularjs1 制作自定义图片查看器(可旋转.放大.缩小.拖拽) 2018-01-12 更新  可以在我的博客  查看我 已经封装好的 纯 js写的图片查看器插件    博客链接 懒得把 ...

  5. angular指令中的scope绑定策略

    针对独立 scope,可以通过在对象中声明如何从外部传入参数.有以下三种绑定策略: @ - 使用 DOM 属性值单项绑定到指令 scope 中.此时绑定的值总是一个字符串,因为 DOM 的属性值是一个 ...

  6. django 使用form组件提交数据之form表单提交

    django的form组件可以减少后台在进行一些重复性的验证工作,极大降低开发效率. 最近遇到一个问题: 当使用form表单提交数据后,如果数据格式不符合后台定义的规则,需要重新在前端页面填写数据. ...

  7. Spring Cloud实战

    Spring Cloud实战(一)-Spring Cloud Config Server https://segmentfault.com/a/1190000006149891 https://seg ...

  8. 浅谈java中源码常见的几个关键字(native,strictfp,transient,volatile)

    最近看源码总发现一些没见过的关键字,今天就来整理一下native,strictfp,transient,volatile native 本地 native是与C++联合开发的时候用的!java自己开发 ...

  9. 二十九 Python分布式爬虫打造搜索引擎Scrapy精讲—selenium模块是一个python操作浏览器软件的一个模块,可以实现js动态网页请求

    selenium模块 selenium模块为第三方模块需要安装,selenium模块是一个操作各种浏览器对应软件的api接口模块 selenium模块是一个操作各种浏览器对应软件的api接口模块,所以 ...

  10. nyoj993——容斥

    How many integers can you find 时间限制:1000 ms  |  内存限制:65535 KB 难度:1   描述 给你三个数,n,m1,m2,找出所有小于n的能被m1或m ...