zoukankan      html  css  js  c++  java
  • HDU

    https://cn.vjudge.net/problem/HDU-3642

    题意

    求立方体相交至少3次的体积。

    分析

    三维的呢。。首先解决至少覆盖三次的问题。则用三个标记,更新时的细节要注意。

    注意到z比较小,于是枚举z一层层求,先求出在这一层的面积交,再乘上前后z的差值,就是体积了。注意离散化。

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <string>
    #include <algorithm>
    #include <cmath>
    #include <ctime>
    #include <vector>
    #include <queue>
    #include <map>
    #include <stack>
    #include <set>
    #include <bitset>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    #define ms(a, b) memset(a, b, sizeof(a))
    #define pb push_back
    #define mp make_pair
    #define pii pair<int, int>
    #define eps 0.0000000001
    #define IOS ios::sync_with_stdio(0);cin.tie(0);
    #define random(a, b) rand()*rand()%(b-a+1)+a
    #define pi acos(-1)
    const ll INF = 0x3f3f3f3f3f3f3f3fll;
    const int inf = 0x3f3f3f3f;
    const int maxn = 20000 + 10;
    const int maxm = 200000 + 10;
    const int mod = 10007;
    
    int n;
    int z[maxn];
    int y[maxn];
    struct LINE{
        int x;
        int y1,y2;
        int z1,z2;
        int flag;
        bool operator <(const LINE &a)const{
            return x<a.x;
        }
    }line[maxn];
    struct ND{
        int l,r;
        int cover;
        bool f;
        int one;//覆盖一次以上的长度
        int two;//覆盖两次以上的长度
        int more;
    }tree[maxn<<2];
    void build(int rt,int l,int r){
        tree[rt].l=y[l];
        tree[rt].r=y[r];
        tree[rt].cover=0;
        tree[rt].one=tree[rt].two=tree[rt].more=0;
        tree[rt].f=false;
        if(l+1==r){
            tree[rt].f=true;
            return;
        }
        int mid = (l+r)>>1;
        build(rt<<1,l,mid);
        build(rt<<1|1,mid,r);
    }
    
    void cal(int rt){
        if(tree[rt].cover>=3){
            tree[rt].more=tree[rt].r-tree[rt].l;
            tree[rt].one=tree[rt].two=0;
        }else if(tree[rt].cover==2){
            if(tree[rt].f){
                tree[rt].more=0;
                tree[rt].two=tree[rt].r-tree[rt].l;
                tree[rt].one=0;
            }else{
                tree[rt].more=tree[rt<<1].one+tree[rt<<1].two+tree[rt<<1].more+
                              tree[rt<<1|1].one+tree[rt<<1|1].two+tree[rt<<1|1].more;
                tree[rt].two=tree[rt].r-tree[rt].l-tree[rt].more;
                tree[rt].one=0;
            }
        }else if(tree[rt].cover==1){
            if(tree[rt].f){
                tree[rt].more=0;
                tree[rt].two=0;
                tree[rt].one=tree[rt].r-tree[rt].l;
            }else{
                tree[rt].more=tree[rt<<1].two+tree[rt<<1].more+
                              tree[rt<<1|1].two+tree[rt<<1|1].more;
                tree[rt].two=tree[rt<<1].one+tree[rt<<1|1].one;
                tree[rt].one=tree[rt].r-tree[rt].l-tree[rt].more-tree[rt].two;
            }
        }else{
            if(tree[rt].f){
                tree[rt].more=tree[rt].one=tree[rt].two=0;
            }else{
                tree[rt].one=tree[rt<<1].one+tree[rt<<1|1].one;
                tree[rt].more=tree[rt<<1].more+tree[rt<<1|1].more;
                tree[rt].two=tree[rt<<1].two+tree[rt<<1|1].two;
            }
        }
    }
    void update(int rt,double l,double r,int flag){
        if(l==tree[rt].l&&r==tree[rt].r){
            tree[rt].cover+=flag;
            cal(rt);
            return;
        }
        if(tree[rt<<1].r>=r) update(rt<<1,l,r,flag);
        else if(l>=tree[rt<<1|1].l) update(rt<<1|1,l,r,flag);
        else{
            update(rt<<1,l,tree[rt<<1].r,flag);
            update(rt<<1|1,tree[rt<<1|1].l,r,flag);
        }
        cal(rt);
    }
    LINE tmp[maxn];
    int main() {
    #ifdef LOCAL
        freopen("in.txt", "r", stdin);
    //    freopen("output.txt", "w", stdout);
    #endif
        int T,cas=1;
        scanf("%d",&T);
        while(T--){
            scanf("%d",&n);
            int cnt=0;
            int x1,x2,y1,y2,z1,z2;
            for(int i=0;i<n;i++){
                scanf("%d%d%d%d%d%d",&x1,&y1,&z1,&x2,&y2,&z2);
                z[cnt]=z1;
                y[cnt]=y1;
                line[cnt].x=x1;
                line[cnt].y1=y1;
                line[cnt].y2=y2;
                line[cnt].z1=z1;
                line[cnt].z2=z2;
                line[cnt++].flag=1;
    
                z[cnt]=z2;
                y[cnt]=y2;
                line[cnt].x=x2;
                line[cnt].y1=y1;
                line[cnt].y2=y2;
                line[cnt].z1=z1;
                line[cnt].z2=z2;
                line[cnt++].flag=-1;
            }
            sort(y,y+cnt);
            sort(line,line+cnt);
            int t1=unique(y,y+cnt)-y;
            build(1,0,t1-1);
            sort(z,z+cnt);
            int t2=unique(z,z+cnt)-z;
            ll ans=0;
            ll area=0;
            for(int i=0;i<t2-1;i++){
                int m=0;
                for(int j=0;j<cnt;j++){
                    if(line[j].z1<=z[i]&&line[j].z2>z[i])
                        tmp[m++]=line[j];
                }
                area=0;
                update(1,tmp[0].y1,tmp[0].y2,tmp[0].flag);
                for(int j=1;j<m;j++){
                    area+=1ll*tree[1].more*(tmp[j].x-tmp[j-1].x);
                    update(1,tmp[j].y1,tmp[j].y2,tmp[j].flag);
                }
                ans+=area*(z[i+1]-z[i]);
            }
            printf("Case %d: %lld
    ",cas++,ans);
        }
        return 0;
    }
  • 相关阅读:
    如何在fragment里面嵌套viewpager?
    textview限制字数,结尾显示。。。。。
    限制imageview大小
    iOS开发核心动画之画图板
    iOS开发核心动画之九宫格解锁
    iOS开发核心动画之Quartz2D绘图
    iOS开发核心动画之触摸手指识别
    iOS开发网络多线程之断点下载
    iOS开发网络多线程之网络请求文件解析
    iOS开发网络多线程之Runloop无限循环
  • 原文地址:https://www.cnblogs.com/fht-litost/p/9580792.html
Copyright © 2011-2022 走看看