题目大意:有$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. 2018.10.09 NOIP模拟 世界杯(图论+set优化)

    传送门 貌似是防akakak题? 不是很清楚. 事实上如果两个人没有严格的大小关系,我们给他们两个连一条边. 这样可以构成很多连通块. 而且对于连通块a,ba,ba,b,aia_iai​和bjb_jb ...

  2. 2018.07.03 BZOJ 1007: [HNOI2008]水平可见直线(简单计算几何)

    1007: [HNOI2008]水平可见直线 Time Limit: 1 Sec Memory Limit: 162 MB Description 在xoy直角坐标平面上有n条直线L1,L2,-Ln, ...

  3. 初识Java ThreadLocal

    转载自:https://www.cnblogs.com/dreamroute/p/5034726.html ThreadLocal翻译成中文比较准确的叫法应该是:线程局部变量. 这个玩意有什么用处,或 ...

  4. python编码(五)

    说说区位码.GB2312.内码和代码页 目前Windows的内核已经采用Unicode编码,这样在内核上可以支持全世界所有的语言文字.但是由于现有的大量程序和文档都采用了某种特定语言的编码,例如GBK ...

  5. Swift的Optional类型

    我们使用Swift这个苹果新推出的编程语言已经有一段时间了.其中的一个极大的优点就是苹果称为“optional types”的东西.几乎所有的objective-c程序员都知道用nil来表示某个引用类 ...

  6. 201709015工作日记--IntentService使用

    一.IntentService与Service的区别 Service 是 Android 四大组件之一,正常来说,我们直接使用 Service 就可以了. 但是 Service 存在几个问题: 默认不 ...

  7. 求解1^2+2^2+3^2+4^2+...+n^2的方法(求解1平方加2平方加3平方...加n平方的和)

    利用公式 (n-1)3 = n3 -3n2 +3n-1 设 S3 = 13 +23 +33 +43 +...+n3 及 S2 = 12 +22 +32 +42 +...+n2 及 S1 = 1 +2 ...

  8. RxJava2 源码分析

    前言 很多项目使用流行的Rxjava2 + Retrofit搭建网络框架,Rxjava现在已经发展到Rxjava2,之前一直都只是再用Rxjava,但从来没有了解下Rxjava的内部实现,接下来一步步 ...

  9. hdu 1799 循环多少次?

    题目 题意:给出n,m,其中m表示有几层循环,求循环的次数 ①如果代码中出现 for(i=1;i<=n;i++) OP ; 那么做了n次OP运算: ②如果代码中出现 fori=1;i<=n ...

  10. node express session

    在express4.0版本以上,需要单独增加session模块:express-session:https://www.npmjs.com/package/express-session 具体做法是, ...