3225: [Sdoi2008]立方体覆盖

Description

  A君近日为准备省队选拔,特意进行了数据结构的专项训练。训练过程中就遇到了“矩形面积并”这道经典问题,即:给出N个各边与坐标轴平行(垂直)的矩形,求矩形覆盖的面积之和。A君按纵坐标建立线段树后按横坐标扫描计算,轻易AC了这道题,时间复杂度为O(NlogN)。
  为了强化训练,A君将问题推广到三维空间中,即:给出N个各棱与坐标轴平行(垂直)的立方体,求立方体覆盖的体积之和。为了简化问题,令立方体均退化为正立方体,用四元组(x, y, z, r)表示一个立方体,其中x, y, z为立方体的中心点坐标,r为中心点到立方体各个面的距离(即立方体高的一半)。
  这次可难住了A君,只好请你——未来的金牌——来帮助他了。

Input

  第一行是一个正整数N。
  以下N行每行四个整数x, y, z, r,由空格隔开。

Output

  共一个数,即覆盖的总体积。

Sample Input

3
0 0 0 3
1 –1 0 1
19 3 5 6

Sample Output

1944

HINT

  对于 100% 的数据,1≤N≤100

  对于 100% 的数据,-1000≤x, y, z≤1000,1≤r≤200

思路

  看到题目的描述,就很容易想到扫描线,但是扫描线是二维的,这道题是三维的,怎么办?

  我们运用扫描线的思想,将这些立方体分隔成为许多的小立方体(如下图)。我们这样就可以每一次计算小立方体就可以了,每一次我们运用扫描线求出众多矩形的面积并,再乘以横向的长度,就可以求出小体积,再将这些小体积相加,就是答案。具体扫描线以及其思想请看:扫描线讲解

代码

#include <cstdio>
#include <algorithm>
using namespace std;
#define N 101
#define inf 1000
int n,cnt,idx,root,ans,tot;
int son[3000<<5][2],times[3000<<5],sum[3000<<5];
struct Surface {int x1,y1,x2,y2,z,kind;}surface[N<<5];
bool cmp1(const Surface &a,const Surface &b) {return a.z<b.z;}
struct Line {int x,y1,y2,kind;}line[N<<1];
bool cmp2(const Line &a,const Line &b) {return a.x<b.x;}
void update(int p,int l,int r)
{(times[p])?sum[p]=r-l+1:sum[p]=sum[son[p][0]]+sum[son[p][1]];}
void change(int &p,int l,int r,int x,int y,int delta)
{
if(!p) p=++cnt;
if(x<=l&&r<=y) {times[p]+=delta,update(p,l,r);return;}
int mid=(l+r)>>1;
if(x<=mid) change(son[p][0],l,mid,x,y,delta);
if(y>mid) change(son[p][1],mid+1,r,x,y,delta);update(p,l,r);
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
int a,b,c,d;scanf("%d%d%d%d",&a,&b,&c,&d);
surface[++idx].z=c-d,surface[idx].x1=a-d;
surface[idx].y1=b+d,surface[idx].x2=a+d;
surface[idx].y2=b-d,surface[idx].kind=1;
surface[++idx].z=c+d,surface[idx].x1=a-d;
surface[idx].y1=b+d,surface[idx].x2=a+d;
surface[idx].y2=b-d,surface[idx].kind=-1;
}
sort(surface+1,surface+idx+1,cmp1),surface[idx+1].z=surface[idx].z;
for(int i=1,tmp=0;i<=idx;tmp=0)
{
int area=0;
while(surface[i].z==surface[i+tmp].z&&i+tmp<=idx) tmp++;
for(int j=0;j<tmp;j++)
{
line[++tot].x=surface[j+i].x1,line[tot].y1=surface[j+i].y2;
line[tot].y2=surface[j+i].y1-1;
line[tot].kind=1*surface[i+j].kind;
line[++tot].x=surface[j+i].x2,line[tot].y1=surface[j+i].y2;
line[tot].y2=surface[j+i].y1-1;
line[tot].kind=-1*surface[i+j].kind;
}sort(line+1,line+tot+1,cmp2);
for(int j=1,now=0;j<=tot;j+=now,now=0)
{
area+=sum[root]*(-line[j-1].x+line[j].x);
while(line[j+now].x==line[j].x)
change(root,-inf,inf,line[j+now].y1,line[j+now].y2
,line[j+now].kind),now++;
}i+=tmp;
ans+=area*(surface[i].z-surface[i-1].z);
}
printf("%d",ans);
}
 

bzoj3225 [Sdoi2008]立方体覆盖——扫描线的更多相关文章

  1. bzoj 3225: [Sdoi2008] 立方体覆盖 题解

    [原题] 3225: [Sdoi2008]立方体覆盖 Time Limit: 2 Sec  Memory Limit: 128 MB Submit: 51  Solved: 36 [Submit][S ...

  2. BZOJ-3225 立方体覆盖 线段树+扫描线+乱搞

    看数据范围像是个暴力,而且理论复杂度似乎可行,然后被卡了两个点...然后来了个乱搞的线段树+扫描线.. 3225: [Sdoi2008]立方体覆盖 Time Limit: 2 Sec Memory L ...

  3. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  4. 【SDOI2008】解题汇总

    好叭我真的是闲的了... /---------------------------------------------/ BZOJ-2037 [SDOI2008]Sue的小球 DP+相关费用提前计算 ...

  5. [C4W1] Convolutional Neural Networks - Foundations of Convolutional Neural Networks

    第一周 卷积神经网络(Foundations of Convolutional Neural Networks) 计算机视觉(Computer vision) 计算机视觉是一个飞速发展的一个领域,这多 ...

  6. HDU 3255 扫描线(立方体体积并变形)

    Farming Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Su ...

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

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

  8. HDU-1255 覆盖的面积 (扫描线)

    题目大意:给若干个矩形,统计重叠次数不为0的面积. 题目分析:维护扫描线的长度时,只需要只统计覆盖次数大于1的区间即可.这是个区间更新,不过不能使用懒标记,但是数据规模不大,不用懒惰标记仍可以AC. ...

  9. ZOJ 3597 Hit the Target! (线段树扫描线 -- 矩形所能覆盖的最多的点数)

    ZOJ 3597 题意是说有n把枪,有m个靶子,每把枪只有一发子弹(也就是说一把枪最多只能打一个靶子), 告诉你第 i 把枪可以打到第j个靶, 现在等概率的出现一个连续的P把枪,在知道这P把枪之后,你 ...

随机推荐

  1. 《Cracking the Coding Interview》——第13章:C和C++——题目8

    2014-04-25 20:27 题目:实现一个能够通过引用计数来实现自动回收数据的智能指针,用C++,不是java. 解法:这题真心牛,我的第一反应是发呆,因为对引用计数的了解仅限于这个名词,完全没 ...

  2. js点击重置按钮重置表单

    <html><head><script type="text/javascript">function formReset(){document ...

  3. Pascal小游戏 贪吃蛇

    一段未完成的Pascal贪吃蛇 说这段代码未完成其实是没有源代码格式化,FP中一行最多只有255字符宽. uses crt; const screenwidth=50; screenheight=24 ...

  4. linux下多线程断点下载工具-axel

    今天要下载一下14G左右的文件,用wget约10小时,后来发现linux下有个多线程支持断点续传的下载工具axel,试了一下,下载速度大大增加. 包地址:http://pkgs.repoforge.o ...

  5. 【APUE】Chapter8 Process Control

    这章的内容比较多.按照小节序号来组织笔记的结构:再结合函数的示例带代码标注出来需要注意的地方. 下面的内容只是个人看书时思考内容的总结,并不能代替看书(毕竟APUE是一本大多数人公认的UNIX圣经). ...

  6. 团队项目-第四次Scrum 会议

    时间:10.26 时长:30分钟 地点:线上 工作情况 团队成员 已完成任务 待完成任务 解小锐 编写project和projectGenerator类 编写下一步的规格说明 陈鑫 采用creator ...

  7. file mmap

    do_set_pmd 统计参数只会在这里设置: add_mm_counter(vma->vm_mm, MM_FILEPAGES, HPAGE_PMD_NR); 但是这貌似都是处理大页的情况哪,小 ...

  8. hdu 3354 Probability One

    Probability One Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

  9. 如何在CentOS7上改变网络接口名

    如何在CentOS7上改变网络接口名 传统上,Linux的网络接口被枚举为eth[0123...],但这些名称并不一定符合实际的硬件插槽,PCI位置,USB接口数量等,这引入了一个不可预知的命名问题( ...

  10. [poj] 1149 PIGS || 最大流经典题目

    原题 题目大意 给你m个猪圈以及每个猪圈里原来有多少头猪,先后给你n个人,每个人能打开一些猪圈并且他们最多想买Ki头猪,在每一个人买完后能将打开的猪圈中的猪顺意分配在这次打开猪圈里,在下一个人来之前 ...