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)
上一篇 2022年2月1日 上午8:00
下一篇 2022年2月1日 上午9:00


相关推荐

  • MyBatis Log Plugin激活码买(注册激活)2022.02.23

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

    2022年4月1日
    99
  • Agent中篇 | 揭秘agent智能体如何思考、决策,并自主执行任务

    Agent中篇 | 揭秘agent智能体如何思考、决策,并自主执行任务

    2026年3月12日
    2
  • 使用 Android Studio 搭建安卓开发环境[通俗易懂]

    使用 Android Studio 搭建安卓开发环境[通俗易懂]使用AndroidStudio搭建安卓开发环境,方便、快捷。因为AndroidSDK等下载已经集成到AndroidStudio的安装中1、官网下载AndroidStudio编辑器首先,访问谷歌中国开发者网站下载AndroidStudio编辑器:https://developer.android.google.cn/studio选择要下…

    2022年4月18日
    468
  • 排列怎么用计算机计算公式,数学排列组合公式计算器

    排列怎么用计算机计算公式,数学排列组合公式计算器数学排列组合公式计算器可以帮助你快速计算排列组合 为学习数学排列组合的朋友带来方便 只要输入相应的数值就能快速计算出结果 帮助你提高效率 节省时间和精力 非常方便快捷 排列组合计算方法 排列 Pnm n 为下标 m 为上标 数 n 的阶乘 n n n 1 n 2 2 1Pnm n n 1 n m 1 Pnm n n m 注 是阶乘符号 Pnn 两个 n 分别为上标和下标

    2026年3月26日
    3
  • 数据转换_数据转换服务是什么意思

    数据转换_数据转换服务是什么意思对数据进行转换就是对数据的合并、清理和整合。通过转换,能够实现不同的源数据在语义上的一致性。SAPBI的转换(Transformation)定义的就是对数据进行处理的规则。当数据从一个BI对象

    2022年8月2日
    9
  • Vim配置pathogen插件管理工具

    Vim配置pathogen插件管理工具1 pathogen 简介通常情况下安装 vim 插件 通常是将所有的插件和相关的 doc 文件都安装在中一文件夹中 如将插件全部安装在 usr share vim vim73 plugin 目录下 将帮助文档全部安装在 usr share vim vim73 doc 目录下 这样做带来的后果是修改和卸载插件很麻烦 很难弄清楚哪个文件属于哪个插件 如果用 pathogen 来管理插件的话 就会变得方便很多了 pa

    2026年3月19日
    3

发表回复

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

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