zoukankan      html  css  js  c++  java
  • HDU

    题意:现在给定空空的三维平面,有加点操作和询问立方体点数。

    思路:考虑CDQ套CDQ。复杂度是O(NlogN*logN*logN),可以过此题。

    具体的,这是一个四维偏序问题,4维分别是(times,x,y,z);我们知道cdq可以求出t<=T,x=X,y<=Y,在套一层就可以z<=Z了。那么一个立方体,我们拆为8个点来容斥。

    然后现在的问题就是,求出(0,0,0)到(x,y,z)的点数。 第一维T已经默认排序了,我们先对X分治。 把所有问题分成两块,并且把左边这块标记o=-1,右边的标记o=1,然后塞到正常的CDQ里面,对y进行分治,对z进行统计。 此时一个z要插入树状数组,需要格外满足o=-1;而询问需要格外满足o=1;

    对于CDQ:先对一维分治,两个小区间搞完后后,归并排序就可以了,这样避开了sort。 这里还可以为了方便用inplace_merge,但是比手写慢一些。

    #include<bits/stdc++.h>
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    const int maxn=400010;
    struct in{
        int x,y,z,id,opt,o; //编号,正负,第一维是否在左
    }s[maxn],q[maxn],fcy[maxn];
    bool cmp1(in w,in v) { return w.x<v.x;}
    bool cmp2(in w,in v) { return w.y<v.y;}
    int b[maxn],sz,tot,cnt,ans[maxn],sum[maxn];
    void add(int x,int val)
    {
        for(int i=x;i<=sz;i+=(-i)&i) sum[i]+=val;
    }
    int query(int x)
    {
        int res=0;
        for(int i=x;i;i-=(-i)&i) res+=sum[i];
        return res;
    }
    void cdq2(int L,int R)
    {
        if(L>=R) return ;
        int Mid=(L+R)>>1,i=L,j=Mid+1,now;
        cdq2(L,Mid); cdq2(Mid+1,R);
        for(;j<=R;j++){
            for(;i<=Mid&&q[i].y<=q[j].y;i++){
                if(q[i].o==-1&&q[i].opt==0) add(q[i].z,1);
            }
            if(q[j].o==1&&q[j].id) ans[q[j].id]+=q[j].opt*query(q[j].z);
        }
        while((--i)>=L) if(q[i].o==-1&&!q[i].id) add(q[i].z,-1);
    
        /*i=L,j=Mid+1,now=L; 手写归并,下面cdq1同理。
        while(j<=R&&i<=Mid){
            if(q[i].y<=q[j].y) fcy[now++]=q[i++];
            else  fcy[now++]=q[j++];
        }
        while(i<=Mid) fcy[now++]=q[i++];
        while(j<=R)  fcy[now++]=q[j++];
        rep(i,L,R) q[i]=fcy[i];*/
        inplace_merge(q+L,q+Mid+1,q+R+1,cmp2); //归并排序
    }
    void cdq1(int L,int R)
    {
        if(L>=R) return ;
        int Mid=(L+R)>>1,i=L,j=Mid+1,now=L;
        cdq1(L,Mid);  cdq1(Mid+1,R);
        //sort(s+L,s+Mid+1,cmp1); sort(s+Mid+1,s+R+1,cmp1);
        tot=0;
        while(j<=R&&i<=Mid){
            if(s[i].x<=s[j].x){
                fcy[now++]=s[i];
                q[++tot]=s[i++],q[tot].o=-1;
                if(s[i-1].id) tot--;
            }
            else {
                fcy[now++]=s[j];
                q[++tot]=s[j++],q[tot].o=1;
                if(!s[j-1].id) tot--;
            }
        }
        while(i<=Mid) {
            fcy[now++]=s[i];
            q[++tot]=s[i++],q[tot].o=-1;
            if(s[i-1].id) tot--;
        }
        while(j<=R) {
            fcy[now++]=s[j];
            q[++tot]=s[j++],q[tot].o=1;
            if(!s[j-1].id) tot--;
        }
        rep(i,L,R) s[i]=fcy[i];
        //inplace_merge(s+L,s+Mid+1,s+R+1,cmp1);
        cdq2(1,tot);
    }
    void solve()
    {
        int N,Q=0,opt,x1,y1,z1,x2,y2,z2;
        sz=0; tot=0;
        scanf("%d",&N);
        rep(i,1,N){
            scanf("%d",&opt);
            if(opt&1){
                scanf("%d%d%d",&x1,&y1,&z1);
                b[++sz]=z1;
                s[++tot]=in{x1,y1,z1,0,0,0};
            }
            else {
                scanf("%d%d%d%d%d%d",&x1,&y1,&z1,&x2,&y2,&z2);
                b[++sz]=z1; b[++sz]=z2; b[++sz]=z1-1; ans[++Q]=0;
                s[++tot]=in{x2,y2,z2,Q,1,0};
                s[++tot]=in{x1-1,y1-1,z1-1,Q,-1,0};
                s[++tot]=in{x1-1,y2,z2,Q,-1,0};
                s[++tot]=in{x1-1,y1-1,z2,Q,1,0};
                s[++tot]=in{x1-1,y2,z1-1,Q,1,0};
                s[++tot]=in{x2,y1-1,z2,Q,-1,0};
                s[++tot]=in{x2,y2,z1-1,Q,-1,0};
                s[++tot]=in{x2,y1-1,z1-1,Q,1,0};
            }
        }
        sort(b+1,b+sz+1);
        cnt=unique(b+1,b+sz+1)-(b+1);
        rep(i,1,tot) s[i].z=lower_bound(b+1,b+sz+1,s[i].z)-b;
        cdq1(1,tot);
        rep(i,1,Q) printf("%d
    ",ans[i]);
    }
    int main()
    {
        int T; scanf("%d",&T);
        while(T--) solve();
        return 0;
    }
  • 相关阅读:
    case when if
    存储过程 、函数和事务
    poj 2263
    hdu -1874
    poj 2472
    2544 hdu
    模板floyed
    模板Dijkstra
    hdu 2066
    hdu 2544
  • 原文地址:https://www.cnblogs.com/hua-dong/p/11516030.html
Copyright © 2011-2022 走看看