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;
}
hdu 3642 Get The Treasury (三维的扫描线)的更多相关文章
- HDU 3642 Get The Treasury (线段树扫描线,求体积并)
参考链接 : http://blog.csdn.net/zxy_snow/article/details/6870127 题意:给你n个立方体,求覆盖三次以上(包括三次)的区域的体积 思路:先将z坐标 ...
- hdu 3642 Get The Treasury(扫描线)
pid=3642" style="">题目链接:hdu 3642 Get The Treasury 题目大意:三维坐标系,给定若干的长方体,问说有多少位置被覆盖3次 ...
- HDU 3642 - Get The Treasury - [加强版扫描线+线段树]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3642 Time Limit: 10000/5000 MS (Java/Others) Memory L ...
- HDU 3642 Get The Treasury 线段树+分层扫描线
http://www.acmerblog.com/hdu-3642-get-the-treasury-6603.html 学习:三维就是把竖坐标离散化分层,每一层进行线段树二维面积并就好了
- HDU 3642 Get The Treasury (线段树扫描线)
题意:给你一些长方体,问你覆盖三次及以上的体积有多大 首先我们观察x轴y轴一样很大,但是z轴很小,所以我们可以枚举z轴(-500,500),注意我们枚举的是每一段长度为一的z轴的xy轴的面积而不是点. ...
- hdu 3642 Get The Treasury
Get The Treasury http://acm.hdu.edu.cn/showproblem.php?pid=3642 Time Limit: 10000/5000 MS (Java/Othe ...
- HDU - 3642 Get The Treasury(线段树求体积交)
https://cn.vjudge.net/problem/HDU-3642 题意 求立方体相交至少3次的体积. 分析 三维的呢..首先解决至少覆盖三次的问题.则用三个标记,更新时的细节要注意. 注意 ...
- HDU 3642 Get The Treasury ( 线段树 求长方体体积并 )
求覆盖三次及其以上的长方体体积并. 这题跟 http://wenku.baidu.com/view/d6f309eb81c758f5f61f6722.html 这里讲的长方体体积并并不一样. 因为本题 ...
- Get The Treasury HDU - 3642(扫描线求三维面积交。。体积交)
题意: ...就是求体积交... 解析: 把每一层z抽出来,计算面积交, 然后加起来即可..! 去看一下 二维面积交的代码 再看看这个三维面积交的代码.. down函数里 你发现了什么规律!!! 参考 ...
随机推荐
- (转)ECSHOP给分类添加代表图
转之--http://www.cnblogs.com/wangblognet/archive/2012/12/09/2809916.html ecshop的模板有很多不完善的地方,比如添加商品分类的时 ...
- 哥的第一个Jquery程序
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs& ...
- android编译系统学习
近日接手了后续android新平台项目搭建的任务. 本文内容基于sprd公司提供的android5.1源码. 一.一般的编译工作流程 我们代码一般情况下是从芯片商SPRD/MTK获得的. 源码的编译上 ...
- ASP.NET性能优化小结
一.返回多个数据集 检查你的访问数据库的代码,看是否存在着要返回多次的请求.每次往返降低了你的应用程序的每秒能够响应请求的次数.通过在单个数据库请求中返回多个结果集,可以减少与数据库通信的时间,使你的 ...
- 抓取锁的sql语句-第二次修改
CREATE OR REPLACE PROCEDURE SOLVE_LOCK AS V_SQL VARCHAR2(3000); --定义 v_sql 接受抓取锁的sql语句 CUR_LOCK SYS ...
- UIScrollView 之图片缩放
UIScrollView 之图片缩放 有些时候,我们可能要对某些内容进行手势缩放,如下图所示 UIScrollView不仅能滚动显示大量内容,还能对其内容进行缩放处理 也就是说,要完成缩放功能的话,只 ...
- C++ nullptr 的一种实现
C/C++ 程序员都应该了解NULL, 0, nullptr, NULL表示空指针,即指针不指向任何对象,C++11后有多了nullptr更好是表了这类概念,看看nullptr是如何实现的: con ...
- protocol buffer VS 2013编译出错
protocol buffer 在VS2013编译会出现以下错误. 解决办法 把宏加上, 问题解决. 注: 该错误只出现在Debug版本.
- POJ 2438 (哈密顿回路)
分析: 2*n个小朋友,每个最多有n-1个"敌人",显然是存在哈密顿回路的. 预处理边,然后找哈密顿回路. code #include <iostream> #incl ...
- [置顶] css 背景透明,文字不透明,alpha滤镜,opacity,position:relative;
都知道,在alpha滤镜下,背景透明了,里面的文字也会跟随透明,我们可以设置内容的position为relative可以解决这个问题 但是在position为absolute这么做却没有效果,怎么解决 ...