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;
}

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 路由器 转接_路由器网络接口

    路由器 转接_路由器网络接口路由器所在的网络位置比较复杂,既可是内部子网边缘,也可位于内、外部网络边缘。同时为了实现强大的适用性,它需要连接各种网络,这样,它的接口也就必须多种多样。对于这些,不要说一般的网络爱好者,就连许多网管人员都无法说清楚。为此笔者向大家全面介绍路由器的各种接口及连接方法。一、路由器接口路由器具有非常强大的网络连接和路由功能,它可以与各种各样的不同网络进行物理连接,这就决定了路由器的接口技术非常复杂,越是高档的路由器其接口种类也就越多,因为它所能连接的网络类型越多。路由器的端口主要分局域网端口、广

    2022年10月19日
  • 【转】游戏黑客亲述盗号全过程 揭露黑客产业链

    【转】游戏黑客亲述盗号全过程 揭露黑客产业链

  • netty什么意思_这篇文章的内容比较优美

    netty什么意思_这篇文章的内容比较优美再有人问你Netty是什么,就把这篇文章发给他

  • pgsql数据库恢复_oracle多字段去重

    pgsql数据库恢复_oracle多字段去重概述今天主要介绍一下Oracle、MySQL、sqlserver、pg数据库在删除重复数据时是怎么实现的。这里用实例来说明。一、Oracle数据库去重1、环境准备可以看到“ALLEN”和“SMITH”这两个人的数据重复了,现在要求表中name重复的数据只保留一行,其他的删除。CREATETABLEhwb(idint,namevarchar(10));INSERTINTOhwbVALUES(1,’TOM’);INSERTINTOhwbVALUES(2

  • tomcat修改http长度限制_解决浏览器与服务器请求url长度限制[通俗易懂]

    tomcat修改http长度限制_解决浏览器与服务器请求url长度限制[通俗易懂]一、前言Http中get与post本身是没有受到长度限制的,受到限制是浏览器与服务器对url长度限制。具体说明请阅读我的零一篇文章《关于HTTPGET/POST请求参数长度最大值的一个理解误区》。二、概述1、服务器限制我目前使用的服务器一般是tomcat+nginx,它们都是通过控制http请求头的长度来进行限制的,nginx的配置参数为large_client_header_buffer…

  • 面试官:Java 到底是值传递还是引用传递?

    点击上方“全栈程序员社区”,星标公众号 重磅干货,第一时间送达 作者:Intopass 来源:知乎,zhihu.com/question/31203609/answer/50992…

发表回复

您的电子邮箱地址不会被公开。

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