三维坐标系中,每次操作增加一个点或者询问一个区域内点的个数。
Kd-tree裸题(cdq套cdq裸题)
模仿treap在Kd-tree中插入节点,一定时间后重建整颗kd_tree
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//Achen
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<ctime>
#include<cmath>
const int N=100000+7;
typedef long long LL;
using namespace std;
int T,D,q,rt,ans,tot,dt[N][3][2],ch[N][2],sz[N];
template<typename T> void read(T &x) {
char ch=getchar(); x=0; T f=1;
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') f=-1,ch=getchar();
for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
}
struct node {
int d[3];
friend bool operator <(const node &A,const node &B) {
return A.d[D]<B.d[D];
}
}a[N],Q[2];
void update(int x) {
for(int i=0;i<3;i++)
for(int j=0;j<2;j++)
dt[x][i][j]=a[x].d[i];
for(int i=0;i<2;i++) {
int y=ch[x][i];
if(y) for(int j=0;j<3;j++)
dt[x][j][0]=min(dt[x][j][0],dt[y][j][0]),
dt[x][j][1]=max(dt[x][j][1],dt[y][j][1]);
}
}
int build(int l,int r,int k) {
if(l>r) return 0;
int mid=((l+r)>>1);
D=k; sz[mid]=r-l+1;
nth_element(a+l,a+mid,a+r+1);
ch[mid][0]=build(l,mid-1,(k+1)%3);
ch[mid][1]=build(mid+1,r,(k+1)%3);
update(mid);
return mid;
}
void insert() {
int x=rt,fa=0,l=0,k=0;
ch[tot][0]=ch[tot][1]=0;
for(;;) {
if(!x) {
update(tot);
sz[tot]=1;
ch[fa][l]=tot;
break;
}
sz[x]++;
for(int j=0;j<3;j++)
dt[x][j][0]=min(dt[x][j][0],a[tot].d[j]),
dt[x][j][1]=max(dt[x][j][1],a[tot].d[j]);
if(a[tot].d[k]<a[x].d[k]) fa=x,l=0,x=ch[x][0];
else fa=x,l=1,x=ch[x][1];
k=(k+1)%3;
}
}
int ck1(int x) {
int res=0;
for(int i=0;i<3;i++)
if(dt[x][i][0]>=Q[0].d[i]&&dt[x][i][1]<=Q[1].d[i]) res++;
return res==3;
}
int ck2(int x) {
int res=1;
for(int i=0;i<3;i++)
if(dt[x][i][0]>Q[1].d[i]||dt[x][i][1]<Q[0].d[i]) res=0;
return res;
}
void qry(int x) {
if(ck1(x)) {ans+=sz[x]; return;}
if(!ck2(x)) return;
int f=0;
for(int i=0;i<3;i++)
if(a[x].d[i]>=Q[0].d[i]&&a[x].d[i]<=Q[1].d[i]) f++;
if(f==3) ans++;
if(ch[x][0]) qry(ch[x][0]);
if(ch[x][1]) qry(ch[x][1]);
}
int main() {
read(T);
while(T--) {
read(q); tot=0; rt=0;
int mod=10000,o;
for(int i=0;i<q;i++) {
read(o);
if(o==1) {
tot++;
for(int j=0;j<3;j++) read(a[tot].d[j]);
insert();
if(i%mod==0||!rt) rt=build(1,tot,0);
}
else {
for(int l=0;l<2;l++)
for(int j=0;j<3;j++) read(Q[l].d[j]);
ans=0; qry(rt);
printf("%d
",ans);
}
}
}
return 0;
}