HDU 3642 Get The Treasury[离散化 + 扫描线 + 线段树]

来源:互联网 发布:linux安装vmware 编辑:程序博客网 时间:2024/06/06 17:06

http://acm.hdu.edu.cn/showproblem.php?pid=3642
给空间中n个立方体,求被这些立方体覆盖过至少3次的区域的体积。
数据范围: |x|106,|y|106,|z|500,1n1000 ,所有坐标都是整数

z坐标范围才1000,直接枚举一下。相当于将这些立方体切成一层层的,每层厚度为1,分别求出每一层至少被覆盖3次的区域的面积即可。也就是对每一层z,找出包含这层的立方体,将它们的xy坐标抽出来,再用平面求被覆盖多次的面积的方法求解,(here)

#include<bits/stdc++.h>using  namespace std;typedef long long int64;#define debug(x) cout<<"debug  "<<x<<endl;#define rep(i,f,t) for(int i = (f),_end = (t); i <= _end; ++i)#define clr(c,x) memset(c,x,sizeof(c));#define MID int mid = (L+R)>>1;#define CHD int lc = node<<1,rc = node<<1|1;struct Node{    int z1,z2,x1,x2,y1,y2;    Node(int z1,int z2,int x1,int y1,int x2,int y2)        :z1(z1),z2(z2),x1(x1),x2(x2),y1(y1),y2(y2){}};struct Node2{    int x,y1,y2;    int flag;    Node2(int x,int y1,int y2,int f)        :x(x),y1(y1),y2(y2),flag(f){}    bool operator< (const Node2 &n2) const{         if(x==n2.x)return flag==1 && n2.flag==-1;        return x < n2.x;    }};vector<int> vs;vector<Node> cube;vector<Node2> line;const int maxn = 2002<<2;struct sgt{    int cov[maxn];    int64 sum[maxn][4];    void init(){        clr(cov,0);        clr(sum,0);    }    void maintain(int node,int L,int R){        int tot = vs[R]-vs[L-1];        clr(sum[node], 0);        rep(i,1,min(3,cov[node]))sum[node][i] = tot;        if(L==R)return;        CHD;        rep(i,cov[node]+1,3){            sum[node][i] = sum[lc][i-cov[node]]+sum[rc][i-cov[node]];        }    }    double query(){        return sum[1][3];    }    void update(int from,int to,int val,int node,int L,int R){        if(from <= L && R <= to){            cov[node] += val;        }else{            MID;CHD;            if(from <= mid)update(from,to,val,lc,L,mid);            if(to > mid) update(from,to,val,rc,mid+1,R);        }        maintain(node,L,R);    }}tree;void pre(){    sort(vs.begin(),vs.end());    vs.erase(unique(vs.begin(),vs.end()),vs.end());    rep(i,0,cube.size()-1){        cube[i].y1 = lower_bound(vs.begin(),vs.end(),cube[i].y1) - vs.begin();        cube[i].y2 = lower_bound(vs.begin(),vs.end(),cube[i].y2) - vs.begin();    }}int64 solve(int z){    line.clear();    tree.init();    rep(i,0,cube.size()-1){        if(cube[i].z1>z || cube[i].z2<=z)continue;        line.push_back(Node2(cube[i].x1,cube[i].y1,cube[i].y2,1));        line.push_back(Node2(cube[i].x2,cube[i].y1,cube[i].y2,-1));    }    sort(line.begin(),line.end());    int64 ans = 0;    int x = line[0].x;    rep(i,0,line.size()-1){        int64 len = tree.query();        ans += len*(line[i].x-x);        x = line[i].x;        tree.update(line[i].y1+1,line[i].y2,line[i].flag,1,1,vs.size()-1);    }    return ans;}int main(){    int n;    int casn;    scanf("%d",&casn);    rep(cas,1,casn){        cube.clear();        vs.clear();        scanf("%d",&n);        int from = 505,to = -1;        rep(i,1,n){            int x1,y1,x2,y2,z1,z2;            scanf("%d%d%d%d%d%d",&x1,&y1,&z1,&x2,&y2,&z2);            vs.push_back(y1);            vs.push_back(y2);            cube.push_back(Node(z1,z2,x1,y1,x2,y2));            from = min(from,z1);            to = max(to,z2);        }        pre();        int64 ans = 0;        rep(z2,from,to){            int64 res = solve(z2);            ans += res;        }        printf("Case %d: %lld\n",cas,ans);    }    return 0;}
0 0
原创粉丝点击