求覆盖三次及其以上的长方体体积并。

这题跟 http://wenku.baidu.com/view/d6f309eb81c758f5f61f6722.html 这里讲的长方体体积并并不一样。

因为本题Z坐标范围非常小,所以可以离散化Z坐标,枚举每个体积块。

对每一个体积块:用底面积*高求其体积。底面积直接用“线段树求长方形面积并”来得到即可。

对于覆盖次数,pushUp的时候:

1.满足 当前覆盖次数大于等于3的,直接求线段长。

2.小于3的,由 左右儿子覆盖次数=3 - 当前覆盖次数 的两个儿子更新上来得到。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm> using namespace std; #define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
#define lc rt << 1
#define rc rt << 1 | 1
#define LL long long int const int MAXN = ; struct cube
{
int x1, y1, z1;
int x2, y2, z2;
void readCube()
{
scanf( "%d%d%d", &x1, &y1, &z1 );
scanf( "%d%d%d", &x2, &y2, &z2 );
return;
}
}cb[MAXN]; struct Line
{
int s; //sao ru sao chu
int x;
int y1, y2;
Line() {}
Line( int s, int x, int y1, int y2 ): s(s), x(x), y1(y1), y2(y2) { }
void showLine()
{
printf("s=%d x=%d y1=%d y2=%d\n", s, x, y1, y2 );
return;
}
}; struct node
{
int cnt;
int len[];
}; int N;
node Tr[ MAXN << ];
Line L[ MAXN << ];
int Z[MAXN << ];
int Y[MAXN << ]; //li san hua
int cntZ, cntY; bool cmp( const Line& a, const Line &b )
{
if ( a.x != b.x ) return a.x < b.x;
return a.s > b.s;
} void build( int l, int r, int rt )
{
for ( int i = ; i < ; ++i )
Tr[rt].len[i] = ;
Tr[rt].cnt = ;
if ( l == r ) return;
int m = ( l + r ) >> ;
build( lson );
build( rson );
return;
} void PushUp( int rt, int l, int r )
{
//len0
if ( Tr[rt].cnt > )
Tr[rt].len[] = Y[r+] - Y[l];
else
Tr[rt].len[] = Tr[lc].len[] + Tr[rc].len[]; //len1
if ( Tr[rt].cnt > )
Tr[rt].len[] = Y[r+] - Y[l];
else if ( Tr[rt].cnt == )
Tr[rt].len[] = Tr[lc].len[] + Tr[rc].len[];
else
Tr[rt].len[] = Tr[lc].len[] + Tr[rc].len[]; //len2
if ( Tr[rt].cnt > )
Tr[rt].len[] = Y[r+] - Y[l];
else if ( Tr[rt].cnt == )
Tr[rt].len[] = Tr[lc].len[] + Tr[rc].len[];
else if ( Tr[rt].cnt == )
Tr[rt].len[] = Tr[lc].len[] + Tr[rc].len[];
else
Tr[rt].len[] = Tr[lc].len[] + Tr[rc].len[]; return;
} void Update( int L, int R, int v, int l, int r, int rt )
{
if ( L <= l && r <= R )
{
Tr[rt].cnt += v;
PushUp( rt, l, r );
return;
}
if ( l == r ) return; int m = ( l + r ) >> ; if ( L <= m ) Update( L, R, v, lson );
if ( R > m ) Update( L, R, v, rson ); PushUp( rt, l, r );
return;
} int main()
{
int T, cas = ;
scanf( "%d", &T );
while ( T-- )
{
scanf( "%d", &N );
cntZ = ;
cntY = ;
for ( int i = ; i < N; ++i )
{
cb[i].readCube();
Z[cntZ++] = cb[i].z1;
Z[cntZ++] = cb[i].z2;
Y[cntY++] = cb[i].y1;
Y[cntY++] = cb[i].y2;
} sort( Z, Z + cntZ );
sort( Y, Y + cntY );
cntZ = unique( Z, Z + cntZ ) - Z;
cntY = unique( Y, Y + cntY ) - Y; LL ans = ;
for ( int i = ; i < cntZ - ; ++i )
{
int cntL = ;
for ( int j = ; j < N; ++j )
{
if ( cb[j].z1 <= Z[i] && cb[j].z2 >= Z[i + ] )
{
L[cntL++] = Line( , cb[j].x1, cb[j].y1, cb[j].y2 );
L[cntL++] = Line(-, cb[j].x2, cb[j].y1, cb[j].y2 );
}
} sort( L, L + cntL, cmp );
build( , cntY - , ); for ( int k = ; k < cntL; ++k )
{
if ( k )
ans += (LL)( L[k].x-L[k-].x )*Tr[].len[]*( Z[i+]-Z[i] );
int a = lower_bound( Y, Y + cntY, L[k].y1 ) - Y;
int b = lower_bound( Y, Y + cntY, L[k].y2 ) - Y - ; //这里一定要减1!!!!!!
Update( a, b, L[k].s, , cntY - , );
}
} printf( "Case %d: %lld\n", ++cas, ans );
}
return ;
}

之前一直调试不出结果,是因为点树和线段树没分清楚,就是线段树节点中存的是一个点,还是一个单位长度倍数的线段。

对于二分得到a,b值,b值需要-1,而pushUp的时候r值需要+1这里并不是很理解。

HDU 3642 Get The Treasury ( 线段树 求长方体体积并 )的更多相关文章

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

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

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

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

  3. hdu 1754 I Hate It (线段树求区间最值)

    HDU1754 I Hate It Time Limit:3000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u D ...

  4. HDU 1828 / POJ 1177 Picture --线段树求矩形周长并

    题意:给n个矩形,求矩形周长并 解法:跟求矩形面积并差不多,不过线段树节点记录的为: len: 此区间线段长度 cover: 此区间是否被整个覆盖 lmark,rmark: 此区间左右端点是否被覆盖 ...

  5. HDU 1264 Counting Squares(线段树求面积的并)

    Counting Squares Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  6. [HDU] 1394 Minimum Inversion Number [线段树求逆序数]

    Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java ...

  7. HDU - 1255 覆盖的面积(线段树求矩形面积交 扫描线+离散化)

    链接:线段树求矩形面积并 扫描线+离散化 1.给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. 2.看完线段树求矩形面积并 的方法后,再看这题,求的是矩形面积交,类同. 求面积时,用被覆 ...

  8. HDU 1394 Minimum Inversion Number(线段树求最小逆序数对)

    HDU 1394 Minimum Inversion Number(线段树求最小逆序数对) ACM 题目地址:HDU 1394 Minimum Inversion Number 题意:  给一个序列由 ...

  9. hdu 1394 (线段树求逆序数)

    <题目链接> 题意描述: 给你一个有0--n-1数字组成的序列,然后进行这样的操作,每次将最前面一个元素放到最后面去会得到一个序列,那么这样就形成了n个序列,那么每个序列都有一个逆序数,找 ...

随机推荐

  1. 创建 XXXXXXXX 的配置节处理程序时出错: 请求失败

    今天碰到这个错误,之前的程序在测试的时候都没有问题,同样的程序打包通过QQ传给其他人,在XP下测试也没有问题,我的Win7系统从QQ信箱下载压缩包,解压之后执行程序就会出问题,本来还是考虑自己程序是不 ...

  2. JS中如何得到触发事件的属性?

    <html xmlns="http://www.w3.org/1999/xhtml"><head runat="server">    ...

  3. 中期ppt制作

    陀螺仪的使用解释:https://zhuanlan.zhihu.com/p/29244429 手机坐标轴的图片:http://jcjs.siat.ac.cn/ch/reader/create_pdf. ...

  4. mingw libgcc_s_sjlj-1.dll is missing

    习惯了在linux环境下工作,编译wingdows平台程序采用mingw工具.编译完,运行exe程序,弹出错误信息: libgcc_s_sjlj-1.dll is missing 百度了一下,原来是编 ...

  5. JQuery基础原理 与实例 验证表单 省市联动 文本框判空 单选 复选 判空 下拉判空 确认密码判等

    JQuery 基础原理 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> & ...

  6. HDU.2111 Saving HDU(贪心)

    题目来源:Saving HDU 题意分析: XHD有个容量为v的口袋,有n个宝贝,每种宝贝的价值不一样,每种宝贝单位体积的价格也不一样,宝贝可以分割,分割后的价值和对应的体积成正比.求XHD最多能取回 ...

  7. Java分享笔记:FileInputStream流的 read()方法 和 read(byte[] b)方法

    /*------------------------ FileInputStream: ....//输入流,字节流 ....//从硬盘中存在的一个文件中读取内容,读取到程序中 ....//read() ...

  8. 【杂题总汇】HDU多校赛第十场 Videos

    [HDU2018多校赛第十场]Videos 最后一场比赛也结束了…… +HDU传送门+ ◇ 题目 <简要翻译> 有n个人以及m部电影,每个人都有一个快乐值.每场电影都有它的开始.结束时间和 ...

  9. datatable常用设置

    bSort: false, // 是否排序功能 bFilter: false, // 过滤功能 bPaginate: true, // 翻页功能 bInfo: true, // 页脚信息 bProce ...

  10. C5509A启动使用定时器

    #include <stdio.h> #include <csl.h> #include <csl_pll.h> #include <csl_chip.h&g ...