hdu 3642 Get The Treasury (三维的扫描线)[通俗易懂]

hdu 3642 Get The Treasury (三维的扫描线)

大家好,又见面了,我是全栈君。

题目大意:

给出N个立方体。

求一个三维空间中被包围三次的空间的体积之和。

思路分析:

发现Z的范围非常小。那么我们能够枚举Z轴,然后对 x y做扫描线。

并且不用枚举全部的Z ,仅仅须要将Z离散化之后枚举。

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#define maxn 2222
#define debug puts("fuck!")
#define lson num<<1,s,mid
#define rson num<<1|1,mid+1,e
typedef long long LL;
using namespace std;

inline void scanf_(int &num){
    char in;
    bool neg=false;
    while(((in=getchar()) > '9' || in<'0') && in!='-') ;
    if(in=='-'){
        neg=true;
        while((in=getchar()) >'9' || in<'0');
    }
    num=in-'0';
    while(in=getchar(),in>='0'&&in<='9')
        num*=10,num+=in-'0';
    if(neg)
        num=0-num;
}

struct node
{
    int x1,y1,z1;
    int x2,y2,z2;
    void scan()
    {
        scanf_(x1);
        scanf_(y1);
        scanf_(z1);
        scanf_(x2);
        scanf_(y2);
        scanf_(z2);
    }
}cube[maxn];

struct line
{
    int s,e,h,type;
    bool operator < (const line &cmp)const
    {
        return h<cmp.h;
    }
}scline[maxn<<1];

int len[maxn<<2][4];
int cov[maxn<<2];
int x[maxn];
int z[maxn];
int cntx,cntz,n;

void init()
{
    cntx=cntz=0;
}

void pushup(int num,int s,int e)
{
        if(cov[num]>=3)
        {
            len[num][3]=len[num][0];
            len[num][1]=len[num][2]=0;
        }
        else if(cov[num]==2)
        {
            if(s==e)
            {
                len[num][1]=len[num][3]=0;
                len[num][2]=len[num][0];
            }
            else
            {
                len[num][3]=len[num<<1][3]+len[num<<1|1][3]+len[num<<1][2]+len[num<<1|1][2]
                            +len[num<<1][1]+len[num<<1|1][1];
                len[num][2]=len[num][0]-len[num][3];
                len[num][1]=0;
            }
        }
        else if(cov[num]==1)
        {
            if(s==e)
            {
                len[num][1]=len[num][0];
                len[num][2]=len[num][3]=0;
            }
            else {
                len[num][3]=len[num<<1][3]+len[num<<1|1][3]+len[num<<1][2]+len[num<<1|1][2];
                len[num][2]=len[num<<1][1]+len[num<<1|1][1];
                len[num][1]=len[num][0]-len[num][2]-len[num][3];
            }
        }
        else
        {
            len[num][3]=len[num<<1][3]+len[num<<1|1][3];
            len[num][2]=len[num<<1][2]+len[num<<1|1][2];
            len[num][1]=len[num<<1][1]+len[num<<1|1][1];
        }
}
void build(int num,int s,int e)
{
    len[num][0]=x[e+1]-x[s];
    len[num][1]=len[num][2]=len[num][3]=0;
    cov[num]=0;

    if(s==e)return;

    int mid=(s+e)>>1;
    build(lson);
    build(rson);
}

void update(int num,int s,int e,int l,int r,int val)
{
    if(l<=s && r>=e)
    {
        cov[num]+=val;

        if(cov[num]>=3)
        {
            len[num][3]=len[num][0];
            len[num][1]=len[num][2]=0;
        }
        else if(cov[num]==2)
        {
            if(s==e)
            {
                len[num][1]=len[num][3]=0;
                len[num][2]=len[num][0];
            }
            else
            {
                len[num][3]=len[num<<1][3]+len[num<<1|1][3]+len[num<<1][2]+len[num<<1|1][2]
                            +len[num<<1][1]+len[num<<1|1][1];
                len[num][2]=len[num][0]-len[num][3];
                len[num][1]=0;
            }
        }
        else if(cov[num]==1)
        {
            if(s==e)
            {
                len[num][1]=len[num][0];
                len[num][2]=len[num][3]=0;
            }
            else {
                len[num][3]=len[num<<1][3]+len[num<<1|1][3]+len[num<<1][2]+len[num<<1|1][2];
                len[num][2]=len[num<<1][1]+len[num<<1|1][1];
                len[num][1]=len[num][0]-len[num][2]-len[num][3];
            }
        }
        else
        {
            len[num][3]=len[num<<1][3]+len[num<<1|1][3];
            len[num][2]=len[num<<1][2]+len[num<<1|1][2];
            len[num][1]=len[num<<1][1]+len[num<<1|1][1];
        }
        return ;
    }

    int mid=(s+e)>>1;

    if(l<=mid)update(lson,l,r,val);
    if(r>mid)update(rson,l,r,val);

    pushup(num,s,e);
}

void solve(int kase)
{
    build(1,0,cntx-2);

    LL ans=0;
    for(int i=0;i<cntz-1;i++)
    {
        int cnt=0;

        for(int j=0;j<n;j++)
        {
            if(cube[j].z1<=z[i] && cube[j].z2>z[i])
            {
                scline[cnt].s=cube[j].x1;
                scline[cnt].e=cube[j].x2;
                scline[cnt].h=cube[j].y1;
                scline[cnt++].type=1;

                scline[cnt].s=cube[j].x1;
                scline[cnt].e=cube[j].x2;
                scline[cnt].h=cube[j].y2;
                scline[cnt++].type=-1;
            }
        }
   
        LL area=0;
        sort(scline,scline+cnt);
       
        for(int j=0;j<cnt-1;j++)
        {
            int l=lower_bound(x,x+cntx,scline[j].s)-x;
            int r=lower_bound(x,x+cntx,scline[j].e)-x;
           
            update(1,0,cntx-2,l,r-1,scline[j].type);
            area+=(LL)len[1][3]*(scline[j+1].h-scline[j].h);
            
        }
        int l=lower_bound(x,x+cntx,scline[cnt-1].s)-x;
        int r=lower_bound(x,x+cntx,scline[cnt-1].e)-x;
        update(1,0,cntx-2,l,r-1,scline[cnt-1].type);
        ans+=area*(z[i+1]-z[i]);
    }
    printf("Case %d: %I64d\n",kase,ans);
}
int main()
{
    int T;
    scanf("%d",&T);
    for(int cas=1;cas<=T;cas++)
    {
        init();

        scanf("%d",&n);

        for(int i=0;i<n;i++)
        {
            cube[i].scan();

            x[cntx++]=cube[i].x1;
            x[cntx++]=cube[i].x2;

            z[cntz++]=cube[i].z1;
            z[cntz++]=cube[i].z2;
        }

        sort(x,x+cntx);
        sort(z,z+cntz);

        cntx=unique(x,x+cntx)-x;
        cntz=unique(z,z+cntz)-z;
      
        solve(cas);
    }
    return 0;
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/115678.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • pycharm2021.8.3永久激活码[最新免费获取]

    (pycharm2021.8.3永久激活码)JetBrains旗下有多款编译器工具(如:IntelliJ、WebStorm、PyCharm等)在各编程领域几乎都占据了垄断地位。建立在开源IntelliJ平台之上,过去15年以来,JetBrains一直在不断发展和完善这个平台。这个平台可以针对您的开发工作流进行微调并且能够提供…

    2022年3月25日
    75
  • 西门子PLC-1200 SCL语言开发学习笔记 (一)

    西门子PLC-1200 SCL语言开发学习笔记 (一)一、简介和背景PLC一般使用梯形图开发,但是梯形图适合电工使用而不是程序员使用,对我们来说开发困难,门槛高,幸好PLC的开发标准还带了类pascal的高级语言,在西门子这里叫SCL语言,这对于我们程序员来说门槛就很低了。要开发好复杂PLC逻辑,梯形图困难重重,市场上要价颇高,而使用SCL语言则非常合适处理复杂逻辑以及运算。二、新建SCL程序块在博图软件的项目视图中,便有添加新快,双击推荐使用FB模块,便于存放变量,语言选择SCL三、变量的创建和访问在打开…

    2022年8月31日
    7
  • HTTPS实现及安全方面

    HTTPS实现及安全方面

    2022年2月13日
    35
  • 字符串匹配算法综述论文_多字符串匹配

    字符串匹配算法综述论文_多字符串匹配字符串匹配算法综述字符串匹配算法综述:BF、RK、KMP、BM、Sunday字符串匹配算法,是在实际工程中经常遇到的问题,也是各大公司笔试面试的常考题目。此算法通常输入为原字符串(string)和子串(pattern),要求返回子串在原字符串中首次出现的位置。比如原字符串为“ABCDEFG”,子串为“DEF”,则算法返回3。常见的算法包括:BF(BruteForce,暴力检索)、RK(R…

    2022年8月21日
    5
  • Python 根据AIC准则定义向前逐步回归进行变量筛选(二)

    Python 根据AIC准则定义向前逐步回归进行变量筛选(二)Python根据AIC准则定义向前逐步回归进行变量筛选(二)AIC简介AIC即赤池值,是衡量模型拟合优良性和模型复杂性的一种标准,在建立多元线性回归模型时,变量过多,且有不显著的变量时,可以使用AIC准则结合逐步回归进行变量筛选。AICD数学表达式如下:AIC=2p+n(log(SSE/n))AIC=2p+n(log(SSE/n))AIC=2p+n(log(SSE/n))其中,ppp…

    2022年5月24日
    182
  • clion永久激活码2020_通用破解码

    clion永久激活码2020_通用破解码,https://javaforall.net/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

    2022年3月16日
    294

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号