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函数里 你发现了什么规律!!! 参考 ...
随机推荐
- 让VC编译出来的程序不依赖于msvcr80.dll/msvcr90.dll/msvcr100.dll等文件
---转载:http://hi.baidu.com/liu_haitao/item/e2157ac3a3c32a0bc610b253 让VC编译出来的程序不依赖于msvcr80.dll/msvcr90 ...
- Tempdb对SQL Server性能的影响
转载文章,原文地址:http://www.cnblogs.com/laodao1/archive/2010/04/15/1712395.html1.SQL Server系统数据库介绍 SQL Serv ...
- 转:常用的HTML标签和属性解释
基本结构标签: <HTML>,表示该文件为HTML文件 <HEAD>,包含文件的标题,使用的脚本,样式定义等 <TITLE>---</TITLE>,包含 ...
- Swift - 20 - 字典的基础操作
//: Playground - noun: a place where people can play import UIKit var dict = [1:"one", 2:& ...
- JavaScript typeof, null, 和 undefined
typeof 操作符 你可以使用 typeof 操作符来检测变量的数据类型. 实例 typeof "John" // 返回 string typeof ...
- 对C#泛型实例化对像--转
最近在编写一套开发框架结构主要应用.Net 3.5以上的框架开发与应用.在此框架中应用了较多的泛型.下面来讲讲对泛型的实例化,以代码为例,如: public class A { } public cl ...
- 对于方法 String.Contains,只支持可在客户端上求值的参数。
var ProjectLevel_XJJS = "06,07,08,09"; p.Where(e =>ProjectLevel_XJJS.Contains(e.LevelCo ...
- Extjs中numberfield小数位数设置
在默认的情况下,使用numberfield控件时只会显示两位小数,有的时候需要根据业务来确定显示小数的位数.通过设置下面的属性可以达到我们想要的目的: text : '存煤量(万吨)', dataIn ...
- WebService cxf 接口中获得拦截器参数
1. 拦截器中put属性 Message message = PhaseInterceptorChain.getCurrentMessage(); message.put("AuthCode ...
- Yii2的相关学习记录,初始化Yii2(二)
前面已经将Yii2下载下来了,那我们就需要能实际的使用. 一.初始化,因为我都是在windows系统下,所以用cmd命令打开下载下来的Yii2的根目录.然后运行下面命令: init 会提示选择0为开发 ...