Get The Treasury【HDU-3642】【扫描线】
题目给出的是N个体积块,问的是有多少体积重叠了3次及以上?
那么就是怎么处理体积这样子的问题了,看到Z的种类不多的时候,就想着从Z离散化的角度去考虑这个问题了,然后就是怎样子去处理面积了,这时候想到每一个Z所代表的这个面对应上的体积,然后把每个面都处理出来看,体积就是在处理X的和,以及求Y、Z的差(差分)来的乘积,所以在处理Z上的时候也有些细节的东西,就是我们要考虑到目前所访问到的这个面积段是否是可以取的,也就是要去判断它的上下Z坐标和目前的区间的上下Z坐标的关系式了。
另外,在处理pushup()的时候,也是需要注意细节,我在这里处理的是"≥times"也就是覆盖次数大于等于1的线段的长、大于等于2的线段的长……
剩下的吧,基本就是写代码上的,细心点,没什么其他的了。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxN = 1e3 + ;
int N, X[maxN<<], tot, Z[maxN<<], cnt, lsan_Z, _UP;
struct IOput
{
int lx, ly, lz, rx, ry, rz;
}a[maxN];
struct node
{
int lx, rx, y, val;
node(int a=, int b=, int c=, int d=):lx(a), rx(b), y(c), val(d) {}
}line[maxN<<];
bool cmp(node e1, node e2) { return e1.y < e2.y; }
struct Tree
{
int siz, sum, len1, len2; //求的是"≥times"的数的个数和
void clear() { siz = sum = len1 = len2 = ; }
}t[maxN<<];
inline void buildTree(int rt, int l, int r)
{
t[rt].clear();
if(l == r) return;
int mid = HalF;
buildTree(Lson);
buildTree(Rson);
}
inline void pushup(int rt, int l, int r)
{
if(t[rt].siz >= )
{
t[rt].sum = t[rt].len2 = t[rt].len1 = X[r + ] - X[l];
}
else if(t[rt].siz == )
{
t[rt].sum = t[lsn].len1 + t[rsn].len1;
t[rt].len2 = t[rt].len1 = X[r + ] - X[l];
}
else if(t[rt].siz == )
{
t[rt].sum = t[lsn].len2 + t[rsn].len2;
if(l == r) t[rt].len2 = ; //相等的时候记得清空对应值
else t[rt].len2 = t[lsn].len1 + t[rsn].len1;
t[rt].len1 = X[r + ] - X[l];
}
else if(l == r) t[rt].clear();
else
{
t[rt].sum = t[lsn].sum + t[rsn].sum;
t[rt].len2 = t[lsn].len2 + t[rsn].len2;
t[rt].len1 = t[lsn].len1 + t[rsn].len1;
}
}
inline void update(int rt, int l, int r, int ql, int qr, int val)
{
if(ql <= l && qr >= r)
{
t[rt].siz += val;
pushup(myself);
return;
}
int mid = HalF;
if(qr <= mid) update(QL, val);
else if(ql > mid) update(QR, val);
else { update(QL, val); update(QR, val); }
pushup(myself);
}
inline void init()
{
cnt = ;
}
int main()
{
int T; scanf("%d", &T);
for(int Cas=; Cas<=T; Cas++)
{
scanf("%d", &N);
init();
for(int i=; i<=N; i++)
{
scanf("%d%d%d%d%d%d", &a[i].lx, &a[i].ly, &a[i].lz, &a[i].rx, &a[i].ry, &a[i].rz);
Z[++cnt] = a[i].lz;
Z[++cnt] = a[i].rz;
}
sort(Z + , Z + cnt + );
lsan_Z = (int)(unique(Z + , Z + cnt + ) - Z - );
ll ans = ;
for(int u=; u<lsan_Z; u++)
{
tot = ;
for(int i=; i<=N; i++)
{
if(a[i].lz <= Z[u] && a[i].rz > Z[u]) //不能计算前面已经算过的部分,就是存在头即尾的情况
{
line[++tot] = node(a[i].lx, a[i].rx, a[i].ly, );
X[tot] = a[i].lx;
line[++tot] = node(a[i].lx, a[i].rx, a[i].ry, -);
X[tot] = a[i].rx;
}
}
sort(line + , line + tot + , cmp);
sort(X + , X + tot + );
_UP = (int)(unique(X + , X + tot + ) - X - );
memset(t, , sizeof(t));
for(int i=, l, r; i<tot; i++)
{
l = (int)(lower_bound(X + , X + _UP + , line[i].lx) - X);
r = (int)(lower_bound(X + , X + _UP + , line[i].rx) - X - );
update(, , _UP, l, r, line[i].val);
ans += (ll)(Z[u + ] - Z[u]) * (ll)(line[i + ].y - line[i].y) * (t[].sum);
}
}
printf("Case %d: %lld\n", Cas, ans);
}
return ;
}
/*
1
6
1 0 0 2 2 2
0 1 0 2 2 2
0 0 1 2 2 2
1 0 0 2 2 2
0 1 0 2 2 2
0 0 1 2 2 2
ans = 4
*/
Get The Treasury【HDU-3642】【扫描线】的更多相关文章
- Get The Treasury HDU - 3642(体积扫描线)
给出n个立方体,要你求这些立方体至少被覆盖三次的部分. 先把这个立方体的信息存在来,发现Z的范围不大,z范围是是[-500,500],所以我们可以先离散化,然后枚举Z, 然后对于每一段Z的区域内,在当 ...
- Get The Treasury HDU - 3642(扫描线求三维面积交。。体积交)
题意: ...就是求体积交... 解析: 把每一层z抽出来,计算面积交, 然后加起来即可..! 去看一下 二维面积交的代码 再看看这个三维面积交的代码.. down函数里 你发现了什么规律!!! 参考 ...
- 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 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://blog.csdn.net/zxy_snow/article/details/6870127 题意:给你n个立方体,求覆盖三次以上(包括三次)的区域的体积 思路:先将z坐标 ...
- hdu 3642 Get The Treasury (三维的扫描线)
题目大意: 给出N个立方体. 求一个三维空间中被包围三次的空间的体积之和. 思路分析: 发现Z的范围非常小.那么我们能够枚举Z轴,然后对 x y做扫描线. 并且不用枚举全部的Z ,仅仅须要将Z离散化之 ...
- HDU 3642 Get The Treasury (线段树扫描线)
题意:给你一些长方体,问你覆盖三次及以上的体积有多大 首先我们观察x轴y轴一样很大,但是z轴很小,所以我们可以枚举z轴(-500,500),注意我们枚举的是每一段长度为一的z轴的xy轴的面积而不是点. ...
- HDU 3642 Get The Treasury 线段树+分层扫描线
http://www.acmerblog.com/hdu-3642-get-the-treasury-6603.html 学习:三维就是把竖坐标离散化分层,每一层进行线段树二维面积并就好了
随机推荐
- Mysql基础篇(笔记)
mysql数据库是由DB跟DBMS跟sql组成 DB 数据库仓库 DBMS 数据库管理系统 SQL 一门通用的数据库语言 数据库启动命令 : 关闭->net stop MySQL || 开启 ...
- mybatis开发注意事项:字段名称以及表名
在使用mybatis开发中,数据库设计的时候字段名称最好不要带下划线,推荐使用驼峰命名法 数据表的名称第一个字母大写
- poj2385 Apple Catching (线性dp)
题目传送门 Apple Catching Apple Catching Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 154 ...
- 自己做的html5手机站点
这个站点採用html5+css3+jquerymobile 仅仅开发了前台的功能,前台的界面比較美观,后端不方便放上,各位有空能够自己开发这个站点的界面有參考各个菜谱站点的页面的样式,可是又不一样,是 ...
- myeclipse 文件注释部分乱码问题
前几天安装了myeclipse,用了几天,写了一些Demo,并且都有注释,今天上午根据要求,重新配置了一下myeclipse,包括许多编码方式的改变,当时没在意,下午打开原来的Demo时,发现它们的注 ...
- SQL 查询中not in 与 not exists 的区别
1.in和exists in是把外表和内表作hash连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询,一直以来认为exists比in效率高的说法是不准确的.如果查询的两个表 ...
- 20191114PHP验证码
<?phpob_clean();$img=imagecreate(40,20);$back=imagecolorallocate($img,200,200,200); $blue=imageco ...
- HashMap、HashTable、ConcurrentHashMap区别
HashMap与HashTable区别 HashMap与ConcurrentHashMap区别 1.HashMap与HashTable的区别 HashMap线程不安全,HashTable线程安全 Ha ...
- CF 49E Common ancestor
传送门 模拟赛T1就自闭了( 才不会说我是去刚T2了来着 感觉非常暴力的一个题? 出题人良心开大数据范围 n=100 还是原来的n^4*26算法我也是自闭了 不过貌似跑不到n^4? 真·大力出奇迹 一 ...
- java知识链接
Java内存模型简称jmm: 它定义了一个线程对另一个线程是可见的,另外就是共享变量的概念,因为Java内存模型又叫做共享内存模型,也就是多个线程会同时访问一个变量,这个变量又叫做共享变量, 共享变量 ...