1. 程式人生 > >bzoj3290: Theresa與數據結構

bzoj3290: Theresa與數據結構

logs amp str rip 一段時間 log bzoj nbsp cal

Description

【題目背景】 Theresa是個愛思考的女孩…… 【問題描述】 這是個復雜的世界。人類社會,自然界,還有地球之外的銀河…… 每一天日出日落,人來人往,步履匆匆。究竟是為什麽呢?那支配著一切的至高無上的法則又是否存在呢?Theresa知道,這個問題並不是一朝一夕就可以解答的,只有在仔細、深入的觀察和思考以後,才有可能將所有支離破碎的線索聯系起來,從而隱約窺見真實的答案。 於是,Theresa經常思考生活中遇到的大大小小的問題。為什麽港臺出版的書籍裏印刷的漢字她一個也不認識呢?為什麽隔夜的白開水中富含一氧化二氫呢?為什麽每年都有一段時間Gmail
郵箱上不去呢?……
為了更加系統、科學地分析這些問題,Theresa決定向你求助。 長話短說,Theresa想請你幫助她實現一個數據結構。這個數據結構的功能是在空間直角坐標系中維護一個點的集合,並支持以下三類操作: 1. ADD x y z 加入一個新的點,點的坐標為(x, y, z)。 2. QUERY x y z r 查詢在正方體(x, y, z) - (x+r, y+r, z+r)內部的點的數目。 3. CANCEL 撤銷最近的一次ADD操作。 其中x, y, z, r
均為給出的整數。QUERY操作中,(x, y, z)為正方體的一個頂點的坐標,r為正方體的邊長。在正方體邊界上的點也算在正方體內部
這個問題可能過於困難,所以Theresa並不強迫你實現一個高效的數據結構。然而,你必須對每一次QUERY操作給出正確的答案。

Input

第一行包含一個整數N,表示最初的點集有N個點。 接下來N行,每行包含三個整數xiyizi,依次表示每個點的坐標。 N+2行包含一個整數Q,表示將有Q次操作。 接下來Q行,每行表示一次操作,格式如題目描述。

Output

輸出若幹行,每行一個整數,依次表示每次查詢操作的答案。

cdq分治 套 cdq分治 套 樹狀數組維護掃描線,時間復雜度$O((n+q)log^3(n+q))$

#include<bits/stdc++.h>
char buf[7000000],*ptr=buf,ob[1500000],*op=ob;
int _(){
    int x=0,f=1;
    while(*ptr<48)*ptr++==-?f=-1:0;
    while(*ptr>47)x=x*10+*ptr++-48;
    return x*f;
}
int _c(){
    while(*ptr<33)++ptr;
    int c=*ptr;
    while(*ptr>32)++ptr;
    return c;
}
void pr(int x){
    int ss[12],sp=0;
    do ss[++sp]=x%10;while(x/=10);
    while(sp)*op++=ss[sp--]+48;
    *op++=10;
}
const int inf=0x3f3f3f3f,N=100007;
void mins(int&a,int b){if(a>b)a=b;}
void maxs(int&a,int b){if(a<b)a=b;}
int n,q;
struct pos{
    int x,y,z;
    void R(){
        x=_(),y=_(),z=_();
    }
}ss[N];
int sp=0,ep=0,qp=0;
int as[N],tk=0,bit[N*2][2],xs[N*2],xp=0;
struct ev{
    int x,y,z,id,sgn;
    void ins(){
        if(id>=0)return;
        for(int w=x;w<=xp;w+=w&-w){
            if(bit[w][0]!=tk)bit[w][0]=tk,bit[w][1]=0;
            bit[w][1]+=sgn;
        }
    }
    void sum(){
        if(id<0)return;
        int s=0;
        for(int w=x;w;w-=w&-w)s+=(bit[w][0]==tk?bit[w][1]:0);
        as[id]+=s*sgn;
    }
}es[N*10],ez[N*10],eb[N*10];
bool cmpy(const ev&a,const ev&b){return a.y<b.y;}
bool cmpz(const ev&a,const ev&b){return a.z!=b.z?a.z<b.z:a.id<b.id;}
void msort(ev*l,ev*m,ev*r){
    ev*p3=eb,*p1=l,*p2=m;
    while(p1!=m&&p2!=r)*p3++=*(p1->y<p2->y?p1:p2)++;
    while(p1!=m)*p3++=*p1++;
    while(p2!=r)*p3++=*p2++;
    memcpy(l,eb,(r-l)*sizeof(ev));
}
int c1;
void cal2(int L,int R){
    c1=0;
    for(int i=L;i<R&&c1<=5;++i)if(ez[i].id<0)++c1;
    if(c1<=5){
        for(int i=L,p=0;i<R;++i)if(ez[i].id>=0){
            for(int j=0;j<p;++j)if(eb[j].x<=ez[i].x&&eb[j].y<=ez[i].y)as[ez[i].id]+=ez[i].sgn*eb[j].sgn;
        }else eb[p++]=ez[i];
        std::sort(ez+L,ez+R,cmpy);
        return;
    }
    int M=L+R>>1;
    cal2(L,M);cal2(M,R);
    ++tk;
    for(int i=M,j=L;i<R;ez[i++].sum())
        for(;j<M&&ez[j].y<=ez[i].y;ez[j++].ins());
    msort(ez+L,ez+M,ez+R);
}
void cal1(int L,int R){
    c1=0;
    for(int i=L;i<R;++i)if(es[i].id<0)++c1;
    if(c1<=200){
        for(int i=L,p=0;i<R;++i)if(es[i].id>=0){
            for(int j=0;j<p;++j)if(eb[j].x<=es[i].x&&eb[j].y<=es[i].y&&eb[j].z<=es[i].z)as[es[i].id]+=es[i].sgn*eb[j].sgn;
        }else eb[p++]=es[i];
        return;
    }
    int M=L+R>>1;
    cal1(L,M);cal1(M,R);
    int p=0,p1;
    for(int i=L;i<M;++i)if(es[i].id<0)ez[p++]=es[i];
    p1=p;
    for(int i=M;i<R;++i)if(es[i].id>=0)ez[p++]=es[i];
    std::sort(ez,ez+p,cmpz);
    if(p1&&p1<p)cal2(0,p);
}
int main(){
    fread(buf,1,sizeof(buf),stdin)[buf]=0;
    n=_();
    for(int i=0;i<n;++i){
        ss[sp].R();
        es[ep++]=(ev){xs[++xp]=ss[sp].x,ss[sp].y,ss[sp].z,-1,1};
        ++sp;
    }
    q=_();
    for(int i=0;i<q;++i){
        int c=_c();
        if(c==A){
            ss[sp].R();
            es[ep++]=(ev){xs[++xp]=ss[sp].x,ss[sp].y,ss[sp].z,-1,1};
            ++sp;
        }else if(c==C){
            --sp;
            es[ep++]=(ev){ss[sp].x,ss[sp].y,ss[sp].z,-1,-1};
        }else{
            int x=_(),y=_(),z=_(),r=_();
            es[ep++]=(ev){x+r,y+r,z+r,qp,1};
            es[ep++]=(ev){x+r,y+r,z-1,qp,-1};
            es[ep++]=(ev){x+r,y-1,z+r,qp,-1};
            es[ep++]=(ev){x+r,y-1,z-1,qp,1};
            es[ep++]=(ev){x-1,y+r,z+r,qp,-1};
            es[ep++]=(ev){x-1,y+r,z-1,qp,1};
            es[ep++]=(ev){x-1,y-1,z+r,qp,1};
            es[ep++]=(ev){x-1,y-1,z-1,qp,-1};
            ++qp;
            xs[++xp]=x+r;
            xs[++xp]=x-1;
        }
    }
    std::sort(xs+1,xs+xp+1);
    for(int i=0;i<ep;++i)es[i].x=std::lower_bound(xs+1,xs+xp+1,es[i].x)-xs;
    cal1(0,ep);
    for(int i=0;i<qp;++i)pr(as[i]);
    fwrite(ob,1,op-ob,stdout);
    return 0;
}

bzoj3290: Theresa與數據結構