HDU - 3642 Get The Treasury (立方体体积交)

求相交三次及以上的立方体体积。

代码参考的kuangbin的博客,

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

const int maxn=2005;

struct node{
    int l,r;
    ll lf,rf;       //实际的左右端点。
    int c;          //覆盖次数。
    ll once,twice,more;
}tree[maxn<<2];

ll x[maxn];
ll z[maxn];

struct Node{
    ll y;
    ll x1,x2;
    ll z1,z2;
    ll f;
}line[maxn],tmp[maxn];

bool cmp(Node a,Node b){
    return a.y<b.y;
}

void build(int i,int l,int r){
    tree[i].l=l;
    tree[i].r=r;
    tree[i].lf=x[l];
    tree[i].rf=x[r];
    tree[i].c=0;
    tree[i].once=tree[i].twice=tree[i].more=0;
    if(r==l+1) return;
    int mid=l+r>>1;
    build(i<<1,l,mid);
    build(i<<1|1,mid,r);
}

void push_up(int i){
    if(tree[i].c>2){
        tree[i].more=tree[i].rf-tree[i].lf;
        tree[i].once=tree[i].twice=0;               //这块很重要。
    }else if(tree[i].c==2){
        if(tree[i].l+1==tree[i].r){                 //叶子节点
            tree[i].more=0;
            tree[i].twice=tree[i].rf-tree[i].lf;
            tree[i].once=0;
            return;
        }
        tree[i].more=tree[i<<1].once+tree[i<<1].twice+tree[i<<1].more+
                    tree[i<<1|1].once+tree[i<<1|1].twice+tree[i<<1|1].more;
        tree[i].twice=tree[i].rf-tree[i].lf-tree[i].more;
        tree[i].once=0;
        return;
    }else if(tree[i].c==1){
        if(tree[i].l+1==tree[i].r){
            tree[i].more=tree[i].twice=0;
            tree[i].once=tree[i].rf-tree[i].lf;
            return;
        }
        tree[i].more=tree[i<<1].twice+tree[i<<1].more+
                    tree[i<<1|1].twice+tree[i<<1|1].more;
        tree[i].twice=tree[i<<1].once+tree[i<<1|1].once;
        tree[i].once=tree[i].rf-tree[i].lf-tree[i].more-tree[i].twice;
    }else{
        if(tree[i].l+1==tree[i].r){
            tree[i].more=tree[i].once=tree[i].twice=0;
            return;
        }
        tree[i].more=tree[i<<1].more+tree[i<<1|1].more;
        tree[i].twice=tree[i<<1].twice+tree[i<<1|1].twice;
        tree[i].once=tree[i<<1].once+tree[i<<1|1].once;
    }
}

void update(int i,Node e){
    if(tree[i].lf>=e.x1&&tree[i].rf<=e.x2){
        tree[i].c+=e.f;
        push_up(i);
        return;
    }
    if(e.x2<=tree[i<<1].rf) update(i<<1,e);
    else if(e.x1>=tree[i<<1|1].lf) update(i<<1|1,e);
    else{
        Node temp=e;
        temp.x2=tree[i<<1].rf;
        update(i<<1,temp);
        temp=e;
        temp.x1=tree[i<<1|1].lf;
        update(i<<1|1,temp);
    }
    push_up(i);
}

int main(){
    int T;
    scanf("%d",&T);
    for(int cs=1;cs<=T;cs++){
        ll x1,x2,y1,y2,z1,z2;
        int n;
        scanf("%d",&n);
        int t=1;
        for(int i=0;i<n;i++){
            scanf("%lld%lld%lld%lld%lld%lld",&x1,&y1,&z1,&x2,&y2,&z2);
            line[t].y=y1;
            line[t].x1=x1;
            line[t].x2=x2;
            line[t].z1=z1;
            line[t].z2=z2;
            line[t].f=1;
            x[t]=x1;
            z[t++]=z1;

            line[t].y=y2;
            line[t].x1=x1;
            line[t].x2=x2;
            line[t].z1=z1;
            line[t].z2=z2;
            line[t].f=-1;
            x[t]=x2;
            z[t++]=z2;
        }
        sort(line+1,line+t,cmp);
        sort(x+1,x+t);
        int t1=unique(x+1,x+t)-x;
        build(1,1,t1-1);
        sort(z+1,z+t);
        int t2=unique(z+1,z+t)-z;
        ll ans=0,area=0;
        for(int i=1;i<t2-1;i++){
            int m=1;
            for(int j=1;j<t;j++){
                if(line[j].z1<=z[i]&&line[j].z2>z[i]){
                    tmp[m++]=line[j];
                }
            }
            area=0;
            update(1,tmp[1]);
            for(int j=2;j<m;j++){
                area+=tree[1].more*(tmp[j].y-tmp[j-1].y);
                update(1,tmp[j]);
            }
            ans+=area*(z[i+1]-z[i]);

        }
        printf("Case %d: %lld\n",cs,ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40679299/article/details/83242262