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


    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
    ",cas,ans);
        }
        return 0;
    }
    

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    ASP.NET Web Form(八)
    ASP.NET Web Form(八)
    软考知识点总结
    软考知识点总结
    c# 引用外部dll
    c# 引用外部dll
    ORA600 [Kcbz_check_objd_typ_1] Running a Job (Doc ID 785899.1)
    oracle创建em
    1918: 等值数目
    1917: 支配值数目
  • 原文地址:https://www.cnblogs.com/DSChan/p/4861974.html
Copyright © 2020-2023  润新知