题目大意:有$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. ubuntu14.04 Samba服务无法访问 可能没有权限 指定的网络名不再可用的问题

    按常规配置后,在windows资源管理器中登陆samba服务器,看得到分享目录却无法打开,弹出"无法访问.您可能没有权限使用网络资源,请与这台服务器的管理员联系以查明您是否有访问权限.指定的 ...

  2. 2018.09.16 bzoj3626: [LNOI2014]LCA(树链剖分)

    传送门 树链剖分好题. 对于每个点维护一个值vi" role="presentation" style="position: relative;"&g ...

  3. CodeForces 611C New Year and Domino (动态规划,DP)

    题意:给定一个h*w的网格,里面只有.和#,.表示空的,#表示禁止的,然后有q个询问,询问中给你两个坐标,分别是左上和右下,求在这两者中间的有多少种(竖着和横着)两个相邻的点. 析:一看到这个题目,肯 ...

  4. 百度地图(icon,zIndex)

    百度地图v2.0参考http://lbsyun.baidu.com/cms/jsapi/reference/jsapi_reference.html#a3b2 覆盖物(Marker) Icon: va ...

  5. ZOJ2478 Encoding 2017-04-18 23:02 43人阅读 评论(0) 收藏

    Encoding Time Limit: 2 Seconds      Memory Limit: 65536 KB Given a string containing only 'A' - 'Z', ...

  6. HashMap底层实现原理以及HashMap与HashTable区别以及HashMap与HashSet区别

    ①HashMap的工作原理 HashMap基于hashing原理,我们通过put()和get()方法储存和获取对象.当我们将键值对传递给put()方法时,它调用键对象的hashCode()方法来计算h ...

  7. hdu 5019

    http://acm.hdu.edu.cn/showproblem.php?pid=5019 给出X 和Y,求出第K 大的 X 和Y 的公约数. 暴力求出所有公约数 #include <cstd ...

  8. colorbox在android上由于高度太高无法scroll问题

    首先看问题截图: 我们可以看到弹出的colorbox页面的高度已经到了下面,你根本看不到"mistake cross"<=>"X". 我测试了iph ...

  9. 【算法34】蓄水池抽样算法 (Reservoir Sampling Algorithm)

    蓄水池抽样算法简介 蓄水池抽样算法随机算法的一种,用来从 N 个样本中随机选择 K 个样本,其中 N 非常大(以至于 N 个样本不能同时放入内存)或者 N 是一个未知数.其时间复杂度为 O(N),包含 ...

  10. Python学习-37.Python中的正则表达式

    作为一门现代语言,正则表达式是必不可缺的,在Python中,正则表达式位于re模块. import re 这里不说正则表达式怎样去匹配,例如\d代表数字,^代表开头(也代表非,例如^a-z则不匹配任何 ...