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. 关于SVN更新注意

    SVN更新时其实大部分都可以直接更新但是只有在 当然为0就没有事但是如果不是0的话就要注意了表示你修改的和别人修改了相同的文件先点开 次文件然后看看那些不一样主要看如果是这样就直接点更新就好了,如果有 ...

  2. [转]SSL协议与数字证书原理

    1 SSL(Secure Socket Lclientyer)是netscclientpe公司设计的主要用于weserver的安全传输协议.这种协议在WESERVER上获得了广泛的应用. SSL在TC ...

  3. codeforces 558/C Amr and Chemistry(数论+位运算)

    题目链接:http://codeforces.com/problemset/problem/558/C 题意:把n个数变成相同所需要走的最小的步数易得到结论,两个奇数不同,一直×2不可能有重叠枚举每个 ...

  4. PAT乙1003

    这次终于觉得智商不够用了,特么的. 总结给你的经验,对于这样字符串的题目,经常会出现一种叫做递归定义的东西. 还有一种叫做,相同的字母表示相同的字符串. 这道题目一共有三个条件. 1. 字符串中必须仅 ...

  5. DataBinding注意事项Error parsing XML: duplicate attribute以及如何在listview中使用DataBinding

    <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...

  6. Mysql中int(2)和int(10)的区别

    int(N)中的N不是限制字段取值范围的,int的取值范围是固定的(0至4294967295)或(-2147483648至2147483647) 那么N这个值是为了在字段中的值不够时补零的,但是必须含 ...

  7. Linux查看端口被哪个进程占用

    netstat -lnp|awk 'BEGIN{prt=":443$"}{if ($4 ~ prt) print $0}' 查看443端口

  8. jQuery获取Select选中的Text和Value,根据Value值动态添加属性等

    语法解释:1. $("#select_id").change(function(){//code...});   //为Select添加事件,当选择其中一项时触发2. var ch ...

  9. Hibernate用Oracle的sequence生成自增Id

    <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBL ...

  10. eclipse中创建NDK和JNI开发环境最简单配置方法

    一.使用环境 1.windows64位操作系统 2.ADT为adt-bundle-windows-x86_64-20130917 3.NDK为android-ndk-r9b 二.配置生成头文件.h ⒈ ...