HDU5126 stars

三维坐标系中,每次操作增加一个点或者询问一个区域内点的个数。

Kd-tree裸题(cdq套cdq裸题)

模仿treap在Kd-tree中插入节点,一定时间后重建整颗kd_tree

//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;
}
View Code
原文地址:https://www.cnblogs.com/Achenchen/p/8021435.html