题目大意:有$m$个操作,分两种:在指定三维坐标内加入一个点,询问指定空间内点的数量。

其中$m≤5*10^{4},1≤x,y,z≤10^9$

这题几乎就是裸的$k-d$树啊。我们动态维护一棵$k-d$树,对于以某个节点为根的字树中,维护该子树中点的三维范围,以及该子树中点的数量。然后直接查询即可。

PS:为了保证你的程序不会变成“优秀”的$n^{2}$做法,需要写一个类似虚树暴力重构的东西,去控制该树的平衡。

#include<bits/stdc++.h>
#define M 100000
using namespace std;
struct node{
int a[],max[],min[],sum,l,r,d;
node(){
a[]=a[]=a[]=; max[]=max[]=max[]=;
min[]=min[]=min[]=; sum=d=l=r=;
}
node(int x,int y,int z){
a[]=x; a[]=y; a[]=z; sum=l=d=r=;
max[]=max[]=max[]=; min[]=min[]=min[]=;
}
node(int x1,int y1,int z1,int x2,int y2,int z2){
max[]=x2; max[]=y2; max[]=z2;
min[]=x1; min[]=y1; min[]=z1;
a[]=a[]=a[]=sum=l=r=d=;
}
}a[M]; int root=,use=;
int id[M]={},rebid=,rebfa=,now=;
void add(int &x,int fa,int d,node k){
if(!x) x=++use,a[x]=k,a[x].d=d;
else{
if(k.a[d]<a[x].a[d]) add(a[x].l,x,(d+)%,k);
else add(a[x].r,x,(d+)%,k);
}
a[x].max[]=max(a[x].max[],k.a[]); a[x].min[]=min(a[x].min[],k.a[]);
a[x].max[]=max(a[x].max[],k.a[]); a[x].min[]=min(a[x].min[],k.a[]);
a[x].max[]=max(a[x].max[],k.a[]); a[x].min[]=min(a[x].min[],k.a[]);
a[x].sum++;
if(max(a[a[x].l].sum,a[a[x].r].sum)>a[x].sum*0.7) rebid=x,rebfa=fa;
}
int D;
bool cmp(int x,int y){
return a[x].a[D]<a[y].a[D];
}
void bl(int x){
if(!x) return; id[++now]=x;
bl(a[x].l); bl(a[x].r);
a[x].max[]=a[x].max[]=a[x].max[]=a[x].l=a[x].r=a[x].sum=a[x].d=;
a[x].min[]=a[x].min[]=a[x].min[]=;
}
void rebuild(int &x,int l,int r,int d){
if(l>r) return; int mid=(l+r)>>; D=d;
nth_element(id+l,id+mid,id+r+,cmp); x=id[mid];
rebuild(a[x].l,l,mid-,(d+)%); rebuild(a[x].r,mid+,r,(d+)%);
for(int i=;i<;i++)
a[x].max[i]=max(a[x].a[i],max(a[a[x].l].max[i],a[a[x].r].max[i])),
a[x].min[i]=min(a[x].a[i],min(a[a[x].l].min[i],a[a[x].r].min[i]));
a[x].sum=a[a[x].l].sum+a[a[x].r].sum+; a[x].d=d;
}
void rebuild(){
if(!rebid) return;
bl(rebid);
if(rebfa==) {rebuild(root,,now,a[rebid].d);}
else{
if(a[rebfa].l==rebid) rebuild(a[rebfa].l,,now,a[rebid].d);
else rebuild(a[rebfa].r,,now,a[rebid].d);
}
rebid=rebfa=now=;
}
int query(int x,node k){
int ck=,sum=; if(!x) return ;
for(int i=;i<;i++) if(k.min[i]<=a[x].min[i]&&a[x].max[i]<=k.max[i]) ck++; if(ck==) return a[x].sum;
for(int i=;i<;i++) if(k.max[i]<a[x].min[i]||a[x].max[i]<k.min[i]) return ; ck=;
for(int i=;i<;i++) if(k.min[i]<=a[x].a[i]&&a[x].a[i]<=k.max[i]) ck++; if(ck==) sum++;
return sum+query(a[x].l,k)+query(a[x].r,k);
}
int main(){
int n; scanf("%d",&n);
while(n--){
int op,x,y,z,x1,y1,z1; scanf("%d%d%d%d",&op,&x,&y,&z);
if(op==) add(root,,,node(x,y,z)),rebuild();
else scanf("%d%d%d",&x1,&y1,&z1),printf("%d\n",query(root,node(x,y,z,x1,y1,z1)));
}
}

【HDU5126】 stars k-d树的更多相关文章

  1. HDU5126 stars【CDQ分治】*

    HDU5126 stars Problem Description John loves to see the sky. A day has Q times. Each time John will ...

  2. 【BZOJ 1901】【Zju 2112】 Dynamic Rankings 动态K值 树状数组套主席树模板题

    达神题解传送门:http://blog.csdn.net/dad3zz/article/details/50638360 说一下我对这个模板的理解: 看到这个方法很容易不知所措,因为动态K值需要套树状 ...

  3. 学习笔记--函数式线段树(主席树)(动态维护第K极值(树状数组套主席树))

    函数式线段树..资瓷 区间第K极值查询 似乎不过似乎划分树的效率更优于它,但是如果主席树套树状数组后,可以处理动态的第K极值.即资瓷插入删除,划分树则不同- 那么原理也比较易懂: 建造一棵线段树(权值 ...

  4. 【BZOJ】1901: Zju2112 Dynamic Rankings(区间第k小+树状数组套主席树)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1901 首先还是吐槽时间,我在zoj交无限tle啊!!!!!!!!我一直以为是程序错了啊啊啊啊啊啊. ...

  5. 【BZOJ】3196: Tyvj 1730 二逼平衡树(区间第k小+树套树)

    http://www.lydsy.com/JudgeOnline/problem.php?id=3196 Treap+树状数组 1WA1A,好伤心,本来是可以直接1A的,这次开始我并没有看题解,就写出 ...

  6. 【BZOJ】1901: Zju2112 Dynamic Rankings(区间第k小+树套树)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1901 这题调了我相当长的时间,1wa1a,我是第一次写树套树,这个是树状数组套splay,在每个区间 ...

  7. hdoj 1541 Stars【线段树单点更新+最大值维护】

    Stars Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submi ...

  8. Stars(BIT树状数组)

    Stars Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submi ...

  9. HDU 1541 Stars (线段树)

     Problem Description Astronomers often examine star maps where stars are represented by points on ...

  10. Dynamic Rankings(动态第k大+树套树)

    题目链接: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1112 题目: 思路: 树套树板子题. 代码实现如下: #inclu ...

随机推荐

  1. win8 app code中设置Resources里定义好的Style

    WPF中应该可以用这个: rectangle.Style = (Style)FindResource("FormLabelStyle"); 但 Win8.1 App是个精简框架,F ...

  2. IntelliJ IDEA 2017版 导入项目项目名称为红色

    1.导入的项目全部是红色的,原因是版本控制问题,所以修改如下:(File--->settings) 2.找到如图位置的字样,选中当前项目,选择铅笔位置 选择铅笔 弹出对话框(默认选择的是proj ...

  3. Caused by: java.lang.IllegalArgumentException: error at ::0 can't find referenced pointcut aaa

    这个错误是说,找不到这个注释: 解决方案: 1.更改自己本机的jdk版本(我的更改了无效): 在工程选择框内点击右键--->build path----->Library--->ad ...

  4. java @option之args4j

    args4j简介 args4j是一个用来配置命令行的工具. 在实际的项目中用到命令行的并不是很常见,但当真正使用到时,特别是在程序启动时配置一下参数的时候就很有用了,如果参数很多的话,一个一个解析命令 ...

  5. [笔记]linux命令学习

    scp /root/Downloads/cymothoa-1-beta.tar.gz root@192.168.1.66:/root/ rc.local exit 0前加入: sh /root/abc ...

  6. SoC FPGA JTAG电路设计 要点

    JTAG协议制定了一种边界扫描的规范,边界扫描架构提供了有效的测试布局紧凑的PCB板上元件的能力.边界扫描可以在不使用物理测试探针的情况下测试引脚连接,并在器件正常工作的过程中捕获运行数据. SoC ...

  7. Java内存模型解惑--观深入理解Java内存模型系列文章有感(二)

    1.volatile关键字修饰的域的特性 当我们声明共享变量为volatile后,对这个变量的读/写将会很特别.理解volatile特性的一个好方法是:把对volatile变量的单个读/写,看成是使用 ...

  8. Linux SSH无密码登录

    Linux服务器常见的登录方式有两种:密码登录.秘钥登录.工作中我们最常使用的是用秘钥登录的方法,因为使用秘钥登录更高效.更安全. 如何实现SSH无密码登录: 原理:无密码ssh登录的主要操作为将本机 ...

  9. LeetCode149:Max Points on a Line

    题目: Given n points on a 2D plane, find the maximum number of points that lie on the same straight li ...

  10. android应用搬家的实现

    android手机上的应用搬家功能,具体的介绍和原理参考: 系统目录及应用搬家的研究 应用搬家的实现 这里主要是作为一个补充,因为上面两篇文章虽然讲的挺好的,但是给出的例子不能直接运行,还是需要一些准 ...