Problem Description
  A number of rectangular posters, photographs and other pictures of the same shape are pasted on a wall. Their sides are all vertical or horizontal. Each rectangle can be partially or totally covered by the others. The length of the boundary of the union of all rectangles is called the perimeter.

  Write a program to calculate the perimeter. An example with 7 rectangles is shown in Figure 1.

The corresponding boundary is the whole set of line segments drawn in Figure 2.

  The vertices of all rectangles have integer coordinates.

 
  题目就是求矩形并的周长和。
  这个题其实和求矩形的面积和没有什么区别,线段树维护的是覆盖区间的总长度,然后扫描线是从左到右扫描,每次计算一个竖边的时候,这一次区间覆盖长度减去上一次区间覆盖长度的绝对值就是变化量,要加到ans上。
  然后就是计算横边的时候有点麻烦,可以再从下到上扫描一遍,从新弄一个线段树。
  不过根据那个杭电大神的做法,是同时再维护三个线段树,分别表示区间内线段端点的个数,区间内左边界是否被覆盖,右边界是否被覆盖,后两个线段树是用来辅助计算前面那个的。然后x的差值乘上线段的个数就是横边的了。
  不过这里要注意先计算还是先更新的问题,横边要先计算,然后更新,然后竖边计算。
 
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm> #define lc po*2
#define rc po*2+1
#define lson L,M,lc
#define rson M+1,R,rc using namespace std; const int maxn=; struct BIAN
{
int x,y1,y2;
short state;
}; BIAN bian[];
bool vis[maxn];
int BIT[maxn*];
int COL[maxn*]; bool lBIT[maxn*],rBIT[maxn*];
int coubian[maxn*]; void pushUP(int L,int R,int po)
{
if(COL[po])
{
BIT[po]=R-L+;
lBIT[po]=rBIT[po]=;
coubian[po]=;
}
else if(L==R)
{
BIT[po]=;
lBIT[po]=rBIT[po]=;
coubian[po]=;
}
else
{
BIT[po]=BIT[lc]+BIT[rc];
lBIT[po]=lBIT[lc];
rBIT[po]=rBIT[rc];
coubian[po]=coubian[lc]+coubian[rc]; if(lBIT[rc]&&rBIT[lc])
coubian[po]-=;
}
} void update(int ul,int ur,int ut,int L,int R,int po)
{
if(ul<=L&&ur>=R)
{
COL[po]+=ut;
pushUP(L,R,po); return;
} int M=(L+R)/; if(ul<=M)
update(ul,ur,ut,lson);
if(ur>M)
update(ul,ur,ut,rson); pushUP(L,R,po);
} bool cmp(BIAN a,BIAN b)
{
return a.x<b.x;
} int main()
{
int N;
int x1,x2,y1,y2;
int ans,last; while(~scanf("%d",&N))
{
ans=;
last=;
memset(COL,,sizeof(COL));
memset(BIT,,sizeof(BIT));
memset(vis,,sizeof(vis));
memset(lBIT,,sizeof(lBIT));
memset(rBIT,,sizeof(rBIT));
memset(coubian,,sizeof(coubian)); for(int i=;i<=N;++i)
{
scanf("%d %d %d %d",&x1,&y1,&x2,&y2); bian[i*-].x=x1;
bian[i*-].y1=y1+;
bian[i*-].y2=y2+;
bian[i*-].state=; bian[i*].x=x2;
bian[i*].y1=y1+;
bian[i*].y2=y2+;
bian[i*].state=-;
} sort(bian+,bian+*N+,cmp); for(int i=;i<=*N;++i)
{
ans+=coubian[]*(bian[i].x-bian[i-].x); update(bian[i].y1,bian[i].y2-,bian[i].state,,,); ans+=abs(BIT[]-last);
last=BIT[];
} printf("%d\n",ans);
} return ;
}

(中等) HDU 1828 Picture,扫描线。的更多相关文章

  1. 51nod 1206 && hdu 1828 Picture (扫描线+离散化+线段树 矩阵周长并)

    1206 Picture  题目来源: IOI 1998 基准时间限制:2 秒 空间限制:131072 KB 分值: 160 难度:6级算法题  收藏  关注 给出平面上的N个矩形(矩形的边平行于X轴 ...

  2. HDU 1828 Picture(长方形的周长和)

    HDU 1828 Picture 题目链接 题意:给定n个矩形,输出矩形周长并 思路:利用线段树去维护,分别从4个方向扫一次,每次多一段的时候,就查询该段未被覆盖的区间长度,然后周长就加上这个长度,4 ...

  3. HDU 1828 Picture(线段树扫描线求周长)

    Picture Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Su ...

  4. HDU 1828“Picture”(线段树+扫描线求矩形周长并)

    传送门 •参考资料 [1]:算法总结:[线段树+扫描线]&矩形覆盖求面积/周长问题(HDU 1542/HDU 1828) •题意 给你 n 个矩形,求矩形并的周长: •题解1(两次扫描线) 周 ...

  5. hdu 1828 Picture(线段树 || 普通hash标记)

    http://acm.hdu.edu.cn/showproblem.php?pid=1828 Picture Time Limit: 6000/2000 MS (Java/Others)    Mem ...

  6. HDU 1828 Picture (线段树+扫描线)(周长并)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1828 给你n个矩形,让你求出总的周长. 类似面积并,面积并是扫描一次,周长并是扫描了两次,x轴一次,y ...

  7. POJ 1177/HDU 1828 picture 线段树+离散化+扫描线 轮廓周长计算

    求n个图矩形放下来,有的重合有些重合一部分有些没重合,求最后总的不规则图型的轮廓长度. 我的做法是对x进行一遍扫描线,再对y做一遍同样的扫描线,相加即可.因为最后的轮廓必定是由不重合的线段长度组成的, ...

  8. hdu 1828 Picture(线段树扫描线矩形周长并)

    线段树扫描线矩形周长并 #include <iostream> #include <cstdio> #include <algorithm> #include &l ...

  9. hdu 1828 Picture(线段树,扫描线)

    A number of rectangular posters, photographs and other pictures of the same shape are pasted on a wa ...

随机推荐

  1. linux 终端相关

    echo cd ~/桌面 >> .bashrc 将终端默认路径设为桌面 -/.bashrc./etc/bash.bashrc./etc/profile这几个文件.这些文件的的作用时机:/e ...

  2. \t 的理解

    在同一个缓冲区内横向跳8个空格. 如果在 \t 前面有字符串,则包括 \t之前出现的字符串之内一共是8个空格.

  3. 介绍两个Android不常用的Drawable:GradientDrawable和 StateListDrawable

    //-------------------------------------------------------------------------------------------------- ...

  4. AutoTile 自动拼接(五) 学习与实践

    今天不讲 权值检索,考虑到后期 自动拼接 做出来 更好玩,操作更方便.所以 今天我 补充一节, 网格计算与操作. 具体就是这么个效果,和地图编辑器一样,不过图块还是没有自然的拼接,这个一定一定是 下一 ...

  5. Bom2016/4/21

    Browser Object Model 浏览器对象模型 open(地址,打开方式) open('http://www.baidu.com','_self')本窗口打开百度 open('http:// ...

  6. lucene-SpanFirstQuery 和SpanNearQuery 跨度查询

    1.SpanFirstQuery查询 对出现在一个域中前n个位置的跨度查询. public void testSpanFirstQuery() throws Exception{ SpanzFirts ...

  7. 11--tag 和transform属性

    tag 和transform属性 1.tag 标签,就相当于身份识别的标码,可以通过tag值获取对应的对象. 2.使用transform 实现对象的平移和旋转. // // ViewControlle ...

  8. CenOS下LAMP搭建过程

    CentOS虚拟机中安装LAMP: Linux+Apache+MySQL+PHP 安装前先关闭防火墙和Selinux 把所有安装包解压到/lamp下(根目录下的lamp目录) 安装gcc, gcc-c ...

  9. Spring注解基本解读

    在一个类中使用Spring对象,办法如下: 使用注解的形式注入 从ApplicationContext中获取. T t = new ApplicationContext.getBean("x ...

  10. MyEclipse8.5 无法安装ADT解决办法

    打开MYECLIPSE.点击菜单栏的help ->my eclipse configure center .然后add site  指向 https://dl-ssl.google.com/an ...