zoukankan      html  css  js  c++  java
  • HDU5126 stars【CDQ分治】*

    HDU5126 stars


    Problem Description

    John loves to see the sky. A day has Q times. Each time John will find a new star in the sky, or he wants to know how many stars between (x1,y1,z1) and (x2,y2,z2).

    Input

    The first line contains a single integer T(1≤T≤10) (the data for Q>100 less than 6 cases),, indicating the number of test cases.
    The first line contains an integer Q(1≤Q≤50000),indicating how many times in a day.
    Next Q lines contain some integers, first input an integer A(1≤A≤2).If A=1 then input 3 integers x, y and z, indicating a coordinate of one star.. If A=2 then input 6 integers x1,y1,z1,x2,y2,z2(1≤x,y,z,x1,y1,z1,x2,y2,z2≤109,x1≤x2,y1≤y2,z1≤z2).

    Output

    For each “A=2”,output an integer means how many stars in such a section.
    Sample Input
    2
    11
    1 1 1 1
    2 1 1 1 1 1 1
    1 2 2 2
    1 1 1 2
    2 1 1 1 2 2 2
    1 3 3 3
    1 4 4 4
    1 5 5 5
    1 6 6 6
    2 1 1 1 6 6 6
    2 3 3 3 6 6 6
    11
    1 1 1 1
    2 1 1 1 1 1 1
    1 2 2 2
    1 1 1 2
    2 1 1 1 2 2 2
    1 3 3 3
    1 4 4 4
    1 5 5 5
    1 6 6 6
    2 1 1 1 6 6 6
    2 3 3 3 6 6 6

    Sample Output

    1
    3
    7
    4
    1
    3
    7
    4


    题意就是问你在给定的三维空间里有多少个点

    CDQ分治

    先把一个三维空间差分成8个节点到(0,0)的三维空间,然后进行维护

    首先CDQ分治掉时间这个维度
    然后再分治掉x坐标这个维度,把左区间的修改和右区间的查询提出来进行处理
    剩下的就变成一个简单的二维偏序,分治一下y就可以了

    简单来说就是CDQ套CDQ


    /*HDU5126 CDQ分治*/
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    using namespace std;
    #define N 500010
    struct BIT{
        int t[N];
        void add(int x,int vl){for(;x<N;x+=x&(-x))t[x]+=vl;}
        int query(int x){int ans=0;for(;x;x-=x&(-x))ans+=t[x];return ans;}
    }T;
    struct Que{
        int x,y,z,id,typ,w;
        Que(){}
        Que(int _x,int _y,int _z,int _id,int _typ,int _w){
            x=_x,y=_y,z=_z,id=_id,typ=_typ,w=_w;
        }
    }q1[N<<3],q2[N<<3],q3[N<<3],q4[N<<3];
    int n,t,pre[N<<1],ans[N];
    vector<int> v;
    bool cmp1(Que a,Que b){
        if(a.x!=b.x)return a.x<b.x;
        return a.id<b.id;
    }
    bool cmp2(Que a,Que b){
        if(a.y!=b.y)return a.y<b.y;
        return a.id<b.id;
    }
    void solve2(int l,int r){
        if(l>=r)return;
        int mid=(l+r)>>1;
        solve2(l,mid);
        solve2(mid+1,r);
        int lenl=0,lenr=0;
        for(int i=l;i<=mid;i++)if(!q2[i].typ)q3[++lenl]=q2[i];
        for(int i=mid+1;i<=r;i++)if(q2[i].typ)q4[++lenr]=q2[i];
        sort(q3+1,q3+lenl+1,cmp2);
        sort(q4+1,q4+lenr+1,cmp2);
        int tl=1,tr=1;
        while(tr<=lenr){
            while(tl<=lenl&&q3[tl].y<=q4[tr].y)T.add(q3[tl].z,1),tl++;
            ans[q4[tr].id]+=q4[tr].w*T.query(q4[tr].z);
            tr++;
        }
        for(int i=1;i<tl;i++)T.add(q3[i].z,-1);
    }
    void solve1(int l,int r){//消除x维的影响
        if(l>=r)return;
        int mid=(l+r)>>1;
        solve1(l,mid);
        solve1(mid+1,r);
        int newq=0;
        for(int i=l;i<=mid;i++)if(!q1[i].typ)q2[++newq]=q1[i];
        for(int i=mid+1;i<=r;i++)if(q1[i].typ)q2[++newq]=q1[i];
        sort(q2+1,q2+newq+1,cmp1);
        solve2(1,newq);
    }
    int main(){
        //freopen("hdu5126.in","r",stdin);
        scanf("%d",&t);
        while(t--){
            v.clear();
            scanf("%d",&n);
            int cnt=0,tot=0;
            memset(ans,0,sizeof(ans));
            for(int i=1;i<=n;i++){
                int op;scanf("%d",&op);
                if(op==1){
                    cnt++;
                    scanf("%d%d%d",&q1[cnt].x,&q1[cnt].y,&q1[cnt].z);
                    q1[cnt].id=i;q1[cnt].typ=0;
                    pre[++tot]=q1[cnt].z;
                }else{
                    int x1,y1,z1,x2,y2,z2;
                    scanf("%d%d%d",&x1,&y1,&z1);
                    scanf("%d%d%d",&x2,&y2,&z2);
                    pre[++tot]=z1-1;
                    pre[++tot]=z2;
                    q1[++cnt]=Que(x2,y2,z2,i,1,1);
                    q1[++cnt]=Que(x1-1,y2,z2,i,1,-1);
                    q1[++cnt]=Que(x2,y1-1,z2,i,1,-1);
                    q1[++cnt]=Que(x2,y2,z1-1,i,1,-1);
                    q1[++cnt]=Que(x1-1,y1-1,z2,i,1,1);
                    q1[++cnt]=Que(x1-1,y2,z1-1,i,1,1);
                    q1[++cnt]=Que(x2,y1-1,z1-1,i,1,1);
                    q1[++cnt]=Que(x1-1,y1-1,z1-1,i,1,-1);
                    v.push_back(i);
                }
            }
            sort(pre+1,pre+tot+1);
            tot=unique(pre+1,pre+tot+1)-pre-1;
            for(int i=1;i<=cnt;i++)q1[i].z=lower_bound(pre+1,pre+tot+1,q1[i].z)-pre;
            solve1(1,cnt);//***cnt!=n
            for(int i=0;i<v.size();i++)printf("%d
    ",ans[v[i]]);
        }
        return 0;
    }
    
  • 相关阅读:
    Redis
    Zookeeper的安装配置及基本开发
    【Unity Shader】新书封面 — Low Polygon风格的渲染
    Hive基本原理及环境搭建
    Hadoop开发环境搭建
    java常用排序算法
    企业人事管理系统项目拾金
    Linux27:分区、格式化与修复
    Linux26:查询磁盘和监控系统资源
    Linux25:文件系统特点与XFS文件系统
  • 原文地址:https://www.cnblogs.com/dream-maker-yk/p/9676328.html
Copyright © 2011-2022 走看看