题目大意:

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

hdu 3642 Get The Treasury (三维的扫描线)的更多相关文章

  1. HDU 3642 Get The Treasury (线段树扫描线,求体积并)

    参考链接 : http://blog.csdn.net/zxy_snow/article/details/6870127 题意:给你n个立方体,求覆盖三次以上(包括三次)的区域的体积 思路:先将z坐标 ...

  2. hdu 3642 Get The Treasury(扫描线)

    pid=3642" style="">题目链接:hdu 3642 Get The Treasury 题目大意:三维坐标系,给定若干的长方体,问说有多少位置被覆盖3次 ...

  3. HDU 3642 - Get The Treasury - [加强版扫描线+线段树]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3642 Time Limit: 10000/5000 MS (Java/Others) Memory L ...

  4. HDU 3642 Get The Treasury 线段树+分层扫描线

    http://www.acmerblog.com/hdu-3642-get-the-treasury-6603.html 学习:三维就是把竖坐标离散化分层,每一层进行线段树二维面积并就好了

  5. HDU 3642 Get The Treasury (线段树扫描线)

    题意:给你一些长方体,问你覆盖三次及以上的体积有多大 首先我们观察x轴y轴一样很大,但是z轴很小,所以我们可以枚举z轴(-500,500),注意我们枚举的是每一段长度为一的z轴的xy轴的面积而不是点. ...

  6. hdu 3642 Get The Treasury

    Get The Treasury http://acm.hdu.edu.cn/showproblem.php?pid=3642 Time Limit: 10000/5000 MS (Java/Othe ...

  7. HDU - 3642 Get The Treasury(线段树求体积交)

    https://cn.vjudge.net/problem/HDU-3642 题意 求立方体相交至少3次的体积. 分析 三维的呢..首先解决至少覆盖三次的问题.则用三个标记,更新时的细节要注意. 注意 ...

  8. HDU 3642 Get The Treasury ( 线段树 求长方体体积并 )

    求覆盖三次及其以上的长方体体积并. 这题跟 http://wenku.baidu.com/view/d6f309eb81c758f5f61f6722.html 这里讲的长方体体积并并不一样. 因为本题 ...

  9. Get The Treasury HDU - 3642(扫描线求三维面积交。。体积交)

    题意: ...就是求体积交... 解析: 把每一层z抽出来,计算面积交, 然后加起来即可..! 去看一下 二维面积交的代码 再看看这个三维面积交的代码.. down函数里 你发现了什么规律!!! 参考 ...

随机推荐

  1. oracle特殊字符的ascii值

  2. 三、C# 运算符和控制流

    通常运算符划分为3大类: 一元运算符.二元运算会.三元运算符,它们对应的操作数分别是1个.2个.3 个. 结合性和优先级顺序. 二元运算会是从左向右结合的,相反赋值运算符是从右向左结合的.   cha ...

  3. Android入门随记

    1.Activity是通过startActivity()开始的,结束后不反回任何结果,而用startActivityForResult(Intent intent, int resquestCode) ...

  4. NOI 191钉子和小球.cpp

    #include<iostream> #include<cstdio> #include<cstring> using namespace std; ][]; in ...

  5. Zsh安装CMake补全脚本进行CMake命令补全

    最近在尝试使用Zsh,发现其补全命令的功能相当厉害.但对CMake命令的补全在默认的5.0.5中好像没有看到,网上找了下关于配置Zsh补全的文章也没有多少.     于是自己动手,发现在Zsh安装目录 ...

  6. ActiveX控件资料

    Visual Studio 2008(c#)开发ActiveX控件及制作CAB包总结(1) 分类: C#2011-05-27 15:50 403人阅读 评论(0) 收藏 举报 c#stringhook ...

  7. 浅析a标签的4个伪类 .

    关于伪类,大家最熟悉的还是a标签的4个伪类::link        有链接属性时:visited    链接地址已被访问过:active     被用户激活(在鼠标点击与释放之间发生的事件):hov ...

  8. jquery学习 (3)文本框获取焦点之后变换样式

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  9. MLlib-分类与回归

    MLlib支持二分类,多酚类和回归分析的多种方法,具体如下: 问题类别 支持方法 二分类 线性支持向量机, 逻辑回归,决策树,朴素贝叶斯 多分类 决策树,朴素贝叶斯 回归 线性最小二乘,Lasso,r ...

  10. Xcode升级导致插件失效的解决办法-b

    作为iOS界的攻城师,每一次水果发布新的Xcode开发版本时,我们都会跟进,然而那些好用的Xcode插件都会莫名的失灵...对此我各种百度,在这里,我将跟大家分享我是如何解决这些问题的.当然,我的方案 ...