• 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
  • 相关阅读:
    单据体内2个字段比较
    立账模式
    余额
    单据服务校验设置
    值更新事件(触发带基础属性到指定字段)
    重建索引 ,压缩数据库
    数据库自动备份
    BZOJ 4597: [Shoi2016]随机序列 线段树 + 思维
    BZOJ 4399: 魔法少女LJJ 线段树合并 + 对数
    BZOJ 2217: [Poi2011]Lollipop 构造 + 思维
  • 原文地址:https://www.cnblogs.com/Achenchen/p/8021435.html
Copyright © 2020-2023  润新知