题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3642

Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)

Problem Description
Jack knows that there is a great underground treasury in a secret region. And he has a special device that can be used to detect treasury under the surface of the earth. One day he got outside with the device to ascertain the treasury. He chose many different locations on the surface of the earth near the secret region. And at each spot he used the device to detect treasury and got some data from it representing a region, which may contain treasury below the surface. The data from the device at each spot is six integers x1, y1, z1, x2, y2 and z2 (x1<x2, y1<y2, z1<z2). According to the instruction of the device they represent the range of x, y and z coordinates of the region. That is to say, the x coordinate of the region, which may contain treasury, ranges from x1 to x2. So do y and z coordinates. The origin of the coordinates is a fixed point under the ground.
Jack can’t get the total volume of the treasury because these regions don’t always contain treasury. Through years of experience, he discovers that if a region is detected that may have treasury at more than two different spots, the region really exist treasure. And now Jack only wants to know the minimum volume of the treasury.
Now Jack entrusts the problem to you.
Input
The first line of the input file contains a single integer t, the number of test cases, followed by the input data for each test case.
Each test case is given in some lines. In the first line there is an integer n (1 ≤ n ≤ 1000), the number of spots on the surface of the earth that he had detected. Then n lines follow, every line contains six integers x1, y1, z1, x2, y2 and z2, separated by a space. The absolute value of x and y coordinates of the vertices is no more than 106, and that of z coordinate is no more than 500.
Output
For each test case, you should output “Case a: b” in a single line. a is the case number, and b is the minimum volume of treasury. The case number is counted from one.
Sample Input
2
1
0 0 0 5 6 4
3
0 0 0 5 5 5
3 3 3 9 10 11
3 3 3 13 20 45
Sample Output
Case 1: 0
Case 2: 8

题意:

给定一些长方体,求这些长方体相交至少3次的体积。

题解:

z坐标的范围 [-500, 500],比较小,所以可以枚举 z平面,用类似于扫描线扫描二维图形的方式,用扫描面扫描整个三维图形,而这些扫描面,就是所有长方体的上下平面,

那么,每个我们扫描得到的截面,就可以按照HDU1542里那样的普通的二维扫描线+线段树来做,求出这样一个截面上,重叠三次及以上的面积有多大,

同时,不难想到,若我们把长方体竖直的四个侧面,看成“下闭上开”(下沿取得到,上沿取不到)的话,当我们枚举到某一个平面 $z_i$ 时,该平面截得的截面,在区间 $\left[ {z_i ,z_{i + 1} } \right)$ 都是不会变动的,这个和普通的二维扫描线+线段树的道理是一样的。

故,枚举到某一个平面 $z_i$ 时,该平面截得的截面积,乘上高度 ${z_{i + 1} - z_i }$ 之后,就是整个“3+次重叠体”在三维区间 $\left[ {z_i ,z_{i + 1} } \right)$ 内的体积。

AC代码:

#include<bits/stdc++.h>
typedef long long ll;
using namespace std; const int maxn=;
const int maxz=; int n; vector<int> x;
inline int getidx(int val){return lower_bound(x.begin(),x.end(),val)-x.begin();} vector<int> z; int tot;
struct Segment
{
int x1,x2,y;
int z1,z2;
int flag;
bool operator <(const Segment &oth)const{
return y<oth.y;
}
}segment[*maxn],tmp[*maxn]; /********************************* Segment Tree - st *********************************/
struct Node{
int l,r;
int s;
int once,twice,more;
void show()
{
printf("l=%d r=%d s=%d once=%d twice=%d more=%d\n",l,r,s,once,twice,more);
}
}node[*maxn];
void pushup(int rt)
{
int ls=rt*,rs=rt*+;
if(node[rt].s>)
{
node[rt].more=x[node[rt].r+]-x[node[rt].l];
node[rt].once=node[rt].twice=;
}
else if(node[rt].s==)
{
if(node[rt].l==node[rt].r)
{
node[rt].more=;
node[rt].twice=x[node[rt].r+]-x[node[rt].l];
node[rt].once=;
}
else
{
node[rt].more=node[ls].once+node[ls].twice+node[ls].more+node[rs].once+node[rs].twice+node[rs].more;
node[rt].twice=x[node[rt].r+]-x[node[rt].l]-node[rt].more;
node[rt].once=;
}
}
else if(node[rt].s==)
{
if(node[rt].l==node[rt].r)
{
node[rt].more=;
node[rt].twice=;
node[rt].once=x[node[rt].r+]-x[node[rt].l];
}
else
{
node[rt].more=node[ls].twice+node[ls].more+node[rs].twice+node[rs].more;
node[rt].twice=node[ls].once+node[rs].once;
node[rt].once=x[node[rt].r+]-x[node[rt].l]-node[rt].more-node[rt].twice;
}
}
else
{
if(node[rt].l==node[rt].r)
{
node[rt].more=;
node[rt].twice=;
node[rt].once=;
}
else
{
node[rt].more=node[ls].more+node[rs].more;
node[rt].twice=node[ls].twice+node[rs].twice;
node[rt].once=node[ls].once+node[rs].once;
}
}
//printf("now pushup rt=%d\t",rt); node[rt].show();
}
void build(int rt,int l,int r)
{
if(l>r) return;
node[rt].l=l; node[rt].r=r;
node[rt].s=;
node[rt].once=node[rt].twice=node[rt].more=;
if(l==r) return;
else
{
int mid=l+(r-l)/;
build(rt*,l,mid);
build(rt*+,mid+,r);
pushup(rt);
}
}
void update(int root,int st,int ed,int val)
{
if(st>node[root].r || ed<node[root].l) return;
if(st<=node[root].l && node[root].r<=ed)
{
node[root].s+=val;
pushup(root);
}
else
{
update(root*,st,ed,val);
update(root*+,st,ed,val);
pushup(root);
}
}
/********************************* Segment Tree - st *********************************/ int main()
{
int T;
scanf("%d",&T);
for(int kase=;kase<=T;kase++)
{
scanf("%d",&n); x.clear();
z.clear();
tot=;
for(int i=;i<=n;i++)
{
int x1,y1,z1,x2,y2,z2;
scanf("%d%d%d%d%d%d",&x1,&y1,&z1,&x2,&y2,&z2); segment[tot].x1=x1; segment[tot].x2=x2; segment[tot].y=y1;
segment[tot].z1=z1; segment[tot].z2=z2;
segment[tot].flag=;
tot++; segment[tot].x1=x1; segment[tot].x2=x2; segment[tot].y=y2;
segment[tot].z1=z1; segment[tot].z2=z2;
segment[tot].flag=-;
tot++; x.push_back(x1);
x.push_back(x2);
z.push_back(z1);
z.push_back(z2);
} sort(x.begin(),x.end());
x.erase(unique(x.begin(),x.end()),x.end()); sort(z.begin(),z.end());
z.erase(unique(z.begin(),z.end()),z.end()); ll ans=;
for(int i=;i<z.size()-;i++)
{
//printf("now z=%d\n",z[i]);
int cnt=;
for(int j=;j<tot;j++) if(segment[j].z1<=z[i] && segment[j].z2>z[i]) tmp[cnt++]=segment[j];
sort(tmp,tmp+cnt); build(,,x.size());
ll area=;
for(int j=;j<cnt-;j++)
{
int l=getidx(tmp[j].x1);
int r=getidx(tmp[j].x2);
//printf("now update y=%d [%d,%d](%d,%d) += %d\n",tmp[j].y,x[l],x[r],l,r-1,tmp[j].flag);
update(,l,r-,tmp[j].flag);
area+=(ll)node[].more*(tmp[j+].y-tmp[j].y);
}
ans+=area*(z[i+]-z[i]);
} printf("Case %d: %I64d\n",kase,ans);
}
}

HDU 3642 - Get The Treasury - [加强版扫描线+线段树]的更多相关文章

  1. HDU 3265/POJ 3832 Posters(扫描线+线段树)(2009 Asia Ningbo Regional)

    Description Ted has a new house with a huge window. In this big summer, Ted decides to decorate the ...

  2. hdu 4419 Colourful Rectangle (离散化扫描线线段树)

    Problem - 4419 题意不难,红绿蓝三种颜色覆盖在平面上,不同颜色的区域相交会产生新的颜色,求每一种颜色的面积大小. 比较明显,这题要从矩形面积并的方向出发.如果做过矩形面积并的题,用线段树 ...

  3. HDU 1255 覆盖的面积 (扫描线 线段树 离散化 矩形面积并)

    题目链接 题意:中文题意. 分析:纯手敲,与上一道题目很相似,但是刚开始我以为只是把cnt>=0改成cnt>=2就行了,. 但是后来发现当当前加入的线段的范围之前 还有线段的时候就不行了, ...

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

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

  5. hdu 3642 Get The Treasury

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

  6. 【BZOJ3958】[WF2011]Mummy Madness 二分+扫描线+线段树

    [BZOJ3958][WF2011]Mummy Madness Description 在2011年ACM-ICPC World Finals上的一次游览中,你碰到了一个埃及古墓. 不幸的是,你打开了 ...

  7. 【bzoj4491】我也不知道题目名字是什么 离线扫描线+线段树

    题目描述 给定一个序列A[i],每次询问l,r,求[l,r]内最长子串,使得该子串为不上升子串或不下降子串 输入 第一行n,表示A数组有多少元素接下来一行为n个整数A[i]接下来一个整数Q,表示询问数 ...

  8. hdu1542 Atlantis(扫描线+线段树+离散)矩形相交面积

    题目链接:点击打开链接 题目描写叙述:给定一些矩形,求这些矩形的总面积.假设有重叠.仅仅算一次 解题思路:扫描线+线段树+离散(代码从上往下扫描) 代码: #include<cstdio> ...

  9. P3722 [AH2017/HNOI2017]影魔(单调栈+扫描线+线段树)

    题面传送门 首先我们把这两个贡献翻译成人话: 区间 \([l,r]\) 产生 \(p_1\) 的贡献当且仅当 \(a_l,a_r\) 分别为区间 \([l,r]\) 的最大值和次大值. 区间 \([l ...

随机推荐

  1. ssh面试题总结

    SSH面试题总结: 题目1:Hibernate工作原理及为什么要用? 原理: hibernate,通过对jdbc进行封装,对 java类和 关系数据库进行mapping,实现了对关系数据库的面向对象方 ...

  2. HttpServletRequest -- 获取请求主机真实的IP地址

    在JSP里,获取客户端的IP地址的方法是:request.getRemoteAddr(),这种方法在大部分情况下都是有效的.但是在通过了 Apache,Nagix等反向代理软件就不能获取到客户端的真实 ...

  3. Git Step by Step – (8) Git的merge和rebase

    前面一篇文章中提到了"git pull"等价于"git fetch"加上"git merge",然后还提到了pull命令支持rebase模式 ...

  4. [AX]AX2012 R2 采购订单的“Request change”

    在采购订单List或者Detail窗口的操作面板上有一个叫做“Request change”的按钮,如果这个按钮是激活的,采购订单不能直接编辑,而必须先使用这个按钮请求修改后,采购订单才能进入编辑状态 ...

  5. 【代码审计】BootCMS v1.1.3 文件上传漏洞分析

      0x00 环境准备 BootCMS官网:http://www.kilofox.net 网站源码版本:BootCMS v1.1.3  发布日期:2016年10月17日 程序源码下载:http://w ...

  6. 使用dshow抓取摄像头数据时,回调函数时间为0的问题

    在使用dshow抓取摄像头数据,调用dshow的回调函数,如果发现SampleTime一直为0,如下图 那极有可能是使用RenderStream函数连接Filter时,指定的第一个参数为 PIN_CA ...

  7. 设置开机自启动VirtualBox虚拟机系统

    如果常用VirtualBox虚拟机系统的话,设置个随开机启动也是很方便的.不需要打开VirtualBox窗口,直接就是系统启动了. 又继续上网搜索学习了.(设置开机自启动VirtualBox虚拟机系统 ...

  8. linux 信息收集脚本。转自insight-labs

    找出所有.sh .pl .py .conf .cnf .ini .*history .*pass* (/usr/share目录里面的除外) 并且在当前目录zip打包.有些时候很多配置文件的权限配置不严 ...

  9. LinQ的初步学习与总结

    嘿嘿,说起来ORM和LinQ,就感觉离我好遥远的,在学校是没有学习的,所以总感觉学习了LinQ就是大神,现在嘛,终于也体会一点,感觉LinQ只是初步学习,没有太难,当然以后使用在项目中就没有这样的简单 ...

  10. 解决react-router 的activeClassName 首页重复匹配问题

    首先先看一下我的inedx.js入口文件: 这是未点击的时候index默认的是选中状态, 这是我点击其他的路由之后:,明显index路由重复了,仔细看了官方文档之后,发现其实Navlink也应该使用e ...