题目链接

题目给出的是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】【扫描线】的更多相关文章

  1. Get The Treasury HDU - 3642(体积扫描线)

    给出n个立方体,要你求这些立方体至少被覆盖三次的部分. 先把这个立方体的信息存在来,发现Z的范围不大,z范围是是[-500,500],所以我们可以先离散化,然后枚举Z, 然后对于每一段Z的区域内,在当 ...

  2. Get The Treasury HDU - 3642(扫描线求三维面积交。。体积交)

    题意: ...就是求体积交... 解析: 把每一层z抽出来,计算面积交, 然后加起来即可..! 去看一下 二维面积交的代码 再看看这个三维面积交的代码.. down函数里 你发现了什么规律!!! 参考 ...

  3. HDU 3642 扫描线(立方体体积并)

    Get The Treasury Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  4. Q - Get The Treasury - HDU 3642 (扫面线求体积)

    题意:求被三个或三个以上立方体重合的体积 分析:就是平面面积的加强,不过归根还是一样的,可以把z轴按照从小向大分区间N个,然后可以得到N个平面,用平面重复三次以上的在和高度计算体积. ******** ...

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

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

  6. HDU 3642 - Get The Treasury - [加强版扫描线+线段树]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3642 Time Limit: 10000/5000 MS (Java/Others) Memory L ...

  7. HDU 3642 Get The Treasury (线段树扫描线,求体积并)

    参考链接 : http://blog.csdn.net/zxy_snow/article/details/6870127 题意:给你n个立方体,求覆盖三次以上(包括三次)的区域的体积 思路:先将z坐标 ...

  8. hdu 3642 Get The Treasury (三维的扫描线)

    题目大意: 给出N个立方体. 求一个三维空间中被包围三次的空间的体积之和. 思路分析: 发现Z的范围非常小.那么我们能够枚举Z轴,然后对 x y做扫描线. 并且不用枚举全部的Z ,仅仅须要将Z离散化之 ...

  9. HDU 3642 Get The Treasury (线段树扫描线)

    题意:给你一些长方体,问你覆盖三次及以上的体积有多大 首先我们观察x轴y轴一样很大,但是z轴很小,所以我们可以枚举z轴(-500,500),注意我们枚举的是每一段长度为一的z轴的xy轴的面积而不是点. ...

  10. HDU 3642 Get The Treasury 线段树+分层扫描线

    http://www.acmerblog.com/hdu-3642-get-the-treasury-6603.html 学习:三维就是把竖坐标离散化分层,每一层进行线段树二维面积并就好了

随机推荐

  1. Java程序流程控制

    程序流程控制有 选择,循环,以及跳转结构 选择结构中无非就是 If 和 switch语句我两种都做了一些小案例 1. 利用Scanner库来获得控制台用户输入的数字与代码中定义的变量比较 packag ...

  2. python 分析 知乎粉丝数据

    昨天花了一下午写了一个小爬虫,用来分析自己的粉丝数据.这个真好玩!今天帮了群里好多大V也爬了他们的数据.运行速度:每分钟5千粉丝以上.暂时先写成这样,这两天要准备补考,没有时间继续玩这个. 下次要改进 ...

  3. 【学习总结】java数据结构和算法-第二章-数据结构和算法概述

    总目录链接 [学习总结]尚硅谷2019java数据结构和算法 github:javaDSA 目录 数据结构和算法的关系 几个实际编程中的问题 线性结构和非线性结构 数据结构和算法的关系 几个实际编程中 ...

  4. 一些常见的js校验

    今天有时间来总结一下那些常用的js校验: vernull = function(value){//非空校验 if(value.trim(value).length == 0){ return fals ...

  5. XMPP即时通讯协议使用(三)——订阅发布、断开重连与Ping

    package com.testV3; import java.util.List; import org.jivesoftware.smack.ConnectionListener; import ...

  6. MySQL MHA相关测试

    接上篇文章,介绍了如何安装mysql mha,地址如下:http://blog.csdn.net/yiyuf/article/details/40340895 下面接着进行mha的相关测试: SSH  ...

  7. java ajax返回 Json 的 几种方式

    原文:https://blog.csdn.net/qq_26289533/article/details/78749057 方式 1. : 自写代码转 Json 需要  HttpHttpServlet ...

  8. List和Tuple的中的method对比

  9. Ubuntu 16.04配置vncviewer

    网上有各种各样的教程,既混乱又复杂.这是提供一个亲自测试可用的配置方案,十分简单,桌面环境选用xfce,Ubuntu版本是16.04. 1 安装 Xfce 和 TightVNC sudo apt in ...

  10. centos6.8安装tomcat多容器的处理办法,及安装zk、dubbo

    系统环境: Linux-centosOS6.8-bit64 JDK1.8 1.Tomcat多容器的处理方案 首先,不论tomcat的版本是否有多个,路径是否相同,肯定的是可以运行多个容器. 处理以下两 ...