题目链接:https://vjudge.net/problem/POJ-1177

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. 

Input

Your program is to read from standard input. The first line contains the number of rectangles pasted on the wall. In each of the subsequent lines, one can find the integer coordinates of the lower left vertex and the upper right vertex of each rectangle. The values of those coordinates are given as ordered pairs consisting of an x-coordinate followed by a y-coordinate.

0 <= number of rectangles < 5000 
All coordinates are in the range [-10000,10000] and any existing rectangle has a positive area.

Output

Your program is to write to standard output. The output must contain a single line with a non-negative integer which corresponds to the perimeter for the input rectangles.

Sample Input

7
-15 0 5 10
-5 8 20 25
15 -4 24 14
0 -6 16 4
2 15 10 22
30 10 36 20
34 0 40 16

Sample Output

228

代码如下:

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
using namespace std;
typedef long long LL;
const double EPS = 1e-;
const int INF = 2e9;
const LL LNF = 2e18;
const int MAXN = 1e4+; struct line
{
int le, ri, h;
int id;
bool operator<(const line &a)const{
return h<a.h;
}
}Line[MAXN]; //X用于离散化横坐标,times为此区间被覆盖的次数,block为有多少块子区间, len为被覆盖的长度
int X[MAXN<<], times[MAXN<<], block[MAXN<<], len[MAXN];
bool usedl[MAXN<<], usedr[MAXN<<];
//usedl用于表示区间的左端是否被覆盖, usedr亦如此 void push_up(int u, int l, int r)
{
if(times[u]>) //该区间有被覆盖
{
len[u] = X[r] - X[l];
block[u] = ;
usedl[u] = usedr[u] = true;
}
else //该区间没有被覆盖
{
if(l+==r) //该区间为单位区间
{
len[u] = ;
block[u] = ;
usedl[u] = usedr[u] = false;
}
else //该区间至少包含两个单位区间
{
len[u] = len[u*] + len[u*+];
block[u] = block[u*] + block[u*+];
if(usedr[u*] && usedl[u*+]) //如果左半区间的右端与右半区间的左端均被覆盖,则他们合成一个子区间
block[u]--;
usedl[u] = usedl[u*];
usedr[u] = usedr[u*+];
}
}
} //此种线段树的操作对象为连续型,即最小的元素为长度为1的区间[l,r],其中l和r只代表端点(r-l>=1),用于确定
//区间的位置和长度,l和r本身没有特别的含义。而以往做的什么单点更新之类的,都属于离散型,在l处和r处是有含义的
void add(int u, int l, int r, int x, int y, int v)
{
if(x<=l && r<=y)
{
times[u] += v;
push_up(u, l, r);
return;
} int mid = (l+r)>>;
if(x<=mid-) add(u*, l, mid, x, y, v);
if(y>=mid+) add(u*+, mid, r, x, y, v);
push_up(u, l, r);
} int main()
{
int n;
while(scanf("%d", &n)!=EOF)
{
for(int i = ; i<=n; i++)
{
int x1, y1, x2, y2;
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
Line[i].le = Line[i+n].le = x1;
Line[i].ri = Line[i+n].ri = x2;
Line[i].h = y1; Line[i+n].h = y2;
Line[i].id = ; Line[i+n].id = -;
X[i] = x1; X[i+n] = x2;
} sort(Line+, Line++*n);
sort(X+, X++*n);
int m = unique(X+, X++*n) - (X+); memset(times, , sizeof(times));
memset(len, , sizeof(len));
memset(block, , sizeof(block));
memset(usedl, false, sizeof(usedl));
memset(usedr, false, sizeof(usedr)); int ans = , pre_len = ;
Line[*n+].h = Line[*n].h; //边界条件
for(int i = ; i<=*n; i++)
{
int l = upper_bound(X+, X++m, Line[i].le) - (X+);
int r = upper_bound(X+, X++m, Line[i].ri) - (X+);
add(, , m, l, r, Line[i].id);
ans += abs(len[] - pre_len); //变化的长度即为显露出来的横向边
ans += *block[]*(Line[i+].h-Line[i].h); //如果有cnt个连续的区间,那么就有2*cnt条显露出来的纵向边
pre_len = len[];
} printf("%d\n", ans);
}
}

POJ1177 Picture —— 求矩形并的周长 线段树 + 扫描线 + 离散化的更多相关文章

  1. hdu1542 Atlantis (线段树+扫描线+离散化)

    Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  2. POJ-1151-Atlantis(线段树+扫描线+离散化)[矩形面积并]

    题意:求矩形面积并 分析:使用线段树+扫描线...因为坐标是浮点数的,因此还需要离散化! 把矩形分成两条边,上边和下边,对横轴建树,然后从下到上扫描上去,用col表示该区间有多少个下边,sum代表该区 ...

  3. poj 1177 Picture (线段树 扫描线 离散化 矩形周长并)

    题目链接 题意:给出n个矩形,每个矩形给左下 和 右上的坐标,求围成的周长的长度. 分析: 首先感谢大神的博客,最近做题经常看大神的博客:http://www.cnblogs.com/kuangbin ...

  4. POJ 1177 Picture(线段树 扫描线 离散化 求矩形并面积)

    题目原网址:http://poj.org/problem?id=1177 题目中文翻译: 解题思路: 总体思路: 1.沿X轴离散化建树 2.按Y值从小到大排序平行与X轴的边,然后顺序处理 如果遇到矩形 ...

  5. HDU1255 覆盖的面积 —— 求矩形交面积 线段树 + 扫描线 + 离散化

    题目链接:https://vjudge.net/problem/HDU-1255 给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. Input输入数据的第一行是一个正整数T(1<= ...

  6. HDU3642 Get The Treasury —— 求矩形交体积 线段树 + 扫描线 + 离散化

    题目链接:https://vjudge.net/problem/HDU-3642 Jack knows that there is a great underground treasury in a ...

  7. HDU1542 Atlantis —— 求矩形面积并 线段树 + 扫描线 + 离散化

    题目链接:https://vjudge.net/problem/HDU-1542 There are several ancient Greek texts that contain descript ...

  8. hdu 4419 线段树 扫描线 离散化 矩形面积

    //离散化 + 扫描线 + 线段树 //这个线段树跟平常不太一样的地方在于记录了区间两个信息,len[i]表示颜色为i的被覆盖的长度为len[i], num[i]表示颜色i 『完全』覆盖了该区间几层. ...

  9. HDU 1542 Atlantis(线段树扫描线+离散化求面积的并)

    Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

随机推荐

  1. kafka flumn sparkstreaming java实现监听文件夹内容保存到Phoenix中

    ps:具体Kafka Flumn SparkStreaming的使用  参考前几篇博客 2.4.6.4.1 配置启动Kafka (1) 在slave机器上配置broker 1) 点击CDH上的kafk ...

  2. String字符串的遍历

    StringTest.java /* * 变量字符串(获取字符串中的每一个字符) */ public class StringTest { public static void main(String ...

  3. python之图形界面GUI开发 Tkinter 2014-4-7

    1.导入Tkinter 可以使用以下三种方法(1)from Tkinter import *#导入Tkinter(2)import TkinterTkinter.methodA使用 Tkinter.m ...

  4. python022 Python3 面向对象

    Python3 面向对象 Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是很容易的.本章节我们将详细介绍Python的面向对象编程. 如果你以前没有接触 ...

  5. Android弹幕编程设计实现的解决方案(一)

     Android弹幕编程设计实现的解决方案(一) 在现在的一些视频类网站.视频类直播网站,比如A站和B站,当视频在播放的时候,会在屏幕上出现一些滚动的字幕,这些字幕是UGC,通常是用户的评论,称之 ...

  6. /etc/fstab readyonly 解决办法

    阿里云主机切换地区强制升级后,“新的磁盘盘符识别为vdb1,但是在/etc/fstab中记录的挂载信息还是旧的xvdb1,导致磁盘挂载失败” 机子启动出错了. 按提示 输入 root的密码,进入以Re ...

  7. myql导入导出命令

    1.导出整个数据库 mysqldump -u 用户名 -p --default-character-set=latin1 数据库名 > 导出的文件名(数据库默认编码是latin1) mysqld ...

  8. csu - 1659 Graph Center(最短路)

    http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1659 题意是找一个图的中心,图的中心定义是某一个点到其他点的最大距离最小,如果有多个排序输出. 注 ...

  9. SOJ 4482 忽悠大神【最小生成树】

    题目链接: http://acm.scu.edu.cn/soj/problem.action?id=4482 题意: 给定边权和点权,从一个点出发并回到该点,减少尽量多的边,每路过点和边都要把权重加到 ...

  10. 怎么配置ODBC microsoft Access 安装(win10)

    笔者看着书配置Access连接方法但就是找不到书中的"Access.mdb". 后来才知道.mdb需要自己创建....对于刚入门的我很无语啊!!!!! 下面带你走出小坑 1.从控制 ...