Get The Treasury HDU - 3642(扫描线求三维面积交。。体积交)
题意:
。。。就是求体积交。。。
解析:
把每一层z抽出来,计算面积交, 然后加起来即可。。!
去看一下 二维面积交的代码 再看看这个三维面积交的代码。。 down函数里 你发现了什么规律!!!
参考二维面积交:https://www.cnblogs.com/WTSRUVF/p/9274318.html
代码如下
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#define mem(a, b) memset(a, b, sizeof(a))
using namespace std;
const int maxn = , INF = 0x7fffffff;
typedef long long LL;
int X[maxn]; struct node{
int l, r, w;
int lx, rx, sum, lsum, llsum;
}Node[maxn]; struct edge{
int lxx, rxx, y, z1, z2;
int f;
}Edge[maxn*]; int cmp(edge a, edge b)
{
return a.y < b.y;
} void build(int k, int ll, int rr)
{
Node[k].l = ll, Node[k].r = rr;
Node[k].w = Node[k].sum = Node[k].lsum = Node[k].llsum = ;
Node[k].lx = X[ll];
Node[k].rx = X[rr];
if(ll + == rr) return;
int m = (ll + rr) / ;
build(k*, ll, m);
build(k*+, m, rr);
} void down(int k)
{
int len = Node[k].rx - Node[k].lx;
if(Node[k].w >= )
{
Node[k].sum = Node[k].lsum = Node[k].llsum = len;
}
else if(Node[k].w == )
{
Node[k].lsum = Node[k].llsum = len;
if(Node[k].l + == Node[k].r)
Node[k].sum = ;
else
Node[k].sum = Node[k*].lsum + Node[k*+].lsum;
}
else if(Node[k].w == )
{
Node[k].lsum = len;
if(Node[k].l + == Node[k].r)
Node[k].llsum = Node[k].sum = ;
else
{
Node[k].llsum = Node[k*].lsum + Node[k*+].lsum;
Node[k].sum = Node[k*].llsum + Node[k*+].llsum;
}
}
else
{
if(Node[k].l + == Node[k].r)
Node[k].sum = Node[k].lsum = Node[k].llsum = ;
else
{
Node[k].lsum = Node[k*].lsum + Node[k*+].lsum;
Node[k].llsum = Node[k*].llsum + Node[k*+].llsum;
Node[k].sum = Node[k*].sum + Node[k*+].sum;
}
} } void update(int k, edge e)
{
if(Node[k].lx == e.lxx && Node[k].rx == e.rxx)
{
Node[k].w += e.f;
down(k);
return;
}
if(e.rxx <= Node[k*].rx) update(k*, e);
else if(e.lxx >= Node[k*+].lx) update(k*+, e);
else
{
edge temp = e;
temp.rxx = Node[k*].rx;
update(k*, temp);
temp = e;
temp.lxx = Node[k*+].lx;
update(k*+, temp);
}
down(k);
} int main()
{
int T, kase = ;
scanf("%d",&T);
while(T--)
{
int n, cnt = ;
scanf("%d",&n);
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);
Edge[++cnt].lxx = x1, Edge[cnt].rxx = x2, Edge[cnt].y = y1, Edge[cnt].f = , Edge[cnt].z1= z1, Edge[cnt].z2 = z2;
X[cnt] = x1;
Edge[++cnt].lxx = x1, Edge[cnt].rxx = x2, Edge[cnt].y = y2, Edge[cnt].f = -, Edge[cnt].z1= z1, Edge[cnt].z2 = z2;
X[cnt] = x2;
}
sort(Edge+, Edge+cnt+, cmp);
sort(X+, X+cnt+);
int m = unique(X+, X+cnt+) - (X+);
LL ret = ;
for(int i=-; i<=; i++)
{
build(, , m);
int ans = ;
edge line[maxn];
for(int j=; j<=cnt; j++)
{
if(Edge[j].z1 <= i && Edge[j].z2 > i)
line[++ans] = Edge[j];
}
for(int j=; j<ans; j++)
{
update(, line[j]);
ret += (LL)Node[].sum * (line[j+].y - line[j].y);
}
}
printf("Case %d: %lld\n",++kase,ret); } return ;
}
Get The Treasury HDU - 3642(扫描线求三维面积交。。体积交)的更多相关文章
- hdu 1542 扫描线求矩形面积的并
很久没做线段树了 求矩形面积的并分析:1.矩形比较多,坐标也很大,所以横坐标需要离散化(纵坐标不需要),熟悉离散化后这个步骤不难,所以这里不详细讲解了,不明白的还请百度2.重点:扫描线法:假想有一条扫 ...
- HDU 1542"Atlantis"(线段树+扫描线求矩形面积并)
传送门 •题意 给你 n 矩形,每个矩形给出你 $(x_1,y_1),(x_2,y_2)$ 分别表示这个矩形的左下角和右上角坐标: 让你求这 n 个矩形并的面积: 其中 $x \leq 10^{5} ...
- Get The Treasury HDU - 3642(体积扫描线)
给出n个立方体,要你求这些立方体至少被覆盖三次的部分. 先把这个立方体的信息存在来,发现Z的范围不大,z范围是是[-500,500],所以我们可以先离散化,然后枚举Z, 然后对于每一段Z的区域内,在当 ...
- HDU 3642 扫描线(立方体体积并)
Get The Treasury Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...
- Q - Get The Treasury - HDU 3642 (扫面线求体积)
题意:求被三个或三个以上立方体重合的体积 分析:就是平面面积的加强,不过归根还是一样的,可以把z轴按照从小向大分区间N个,然后可以得到N个平面,用平面重复三次以上的在和高度计算体积. ******** ...
- hdu 1542&&poj 1151 Atlantis[线段树+扫描线求矩形面积的并]
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- HDU 3265 扫描线(矩形面积并变形)
Posters Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Sub ...
- hdu1828 线段树扫描线求矩形面积的周长
题意: 给你n个矩形,问你这n个矩形所围成的图形的周长是多少. 思路: 线段树的扫描线简单应用,这个题目我用的方法比较笨,就是扫描两次,上下扫描,求出多边形的上下边长和,然后同 ...
- hdu1542 线段树扫描线求矩形面积的并
题意: 给你n个正方形,求出他们的所占面积有多大,重叠的部分只能算一次. 思路: 自己的第一道线段树扫描线题目,至于扫描线,最近会写一个总结,现在就不直接在这里写了,说下我的方 ...
随机推荐
- eclipse 报错Version 1.6.0_45 of the JVM is not suitable for this product. Version:1.7 or greater is required
最近离职来了一家新公司,之前的公司的开发IDE用的是IntelliJIDEA和SpringSourceToolSuit,自己在家里用的也是MyEclipse,所以使用eclipse的经验还是不足.结果 ...
- Luogu3220 HNOI2012 与非 数位DP
传送门 题意:给出$N$个范围在$[0,2^k-1]$的整数,定义位运算$NAND$为位运算$AND$的逆运算,求$[L,R]$中有多少数能成为若干个前面给出的整数.若干括号和$NAND$运算组成的表 ...
- React-本地状态(state)
在类组件中添加本地状态(state): 1.创建一个继承自 React.Component 类的 ES6 class 同名类: 2.添加一个 类构造函数(class constructor) 初始化 ...
- NOIp2018停课刷题记录
Preface 老叶说了高中停课但是初中不停的消息后我就为争取民主献出一份力量 其实就是和老师申请了下让我们HW的三个人听课结果真停了 那么还是珍惜这次机会好好提升下自己吧不然就\(AFO\)了 Li ...
- POJ1850&&1019&&1942
这三道题都水的难以想象,所以就放在一起写 1850 题目大意:有一种一种序列排列方式(如同题目中给出的例子),然后给你一个序列,问你这个序列的排名 首先我们先判断无解的情况,这个就很简单了. 由于题目 ...
- Windows 窗体中的事件顺序
来自:https://docs.microsoft.com/zh-cn/dotnet/framework/winforms/order-of-events-in-windows-forms 对于依次处 ...
- Flutter - 本地化启动列表中App名字
上一篇讲了 Flutter - 本地化语言 但是这还有一点小欠缺,就是启动器中的App名字还是无法本地化. 比如英文系统中Play Store,在中文手机中就会显示Play 商店 那么为了解决这个问题 ...
- Centos下SFTP双机高可用环境部署记录
SFTP(SSH File Transfer Protocol),安全文件传送协议.有时也被称作 Secure File Transfer Protocol 或 SFTP.它和SCP的区别是它允许用户 ...
- Docker容器学习梳理 - 基础环境安装
以下是centos系统安装docker的操作记录 1)第一种方法:采用系统自带的docker安装,但是这一般都不是最新版的docker安装epel源[root@docker-server ~]# wg ...
- C. Multi-Subject Competition
链接 [https://codeforces.com/contest/1082/problem/C] 题意 有n个人,m个科目,每个人都有选的科目si,以及他的能力值ri, 规则是每个科目要么选要么不 ...