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 <cstring>
#include <algorithm>
#include <cmath>
#include <cstdio>
using namespace std;
typedef long long LL;
const int maxn = 5e4 + ;
#define rtl rt<<1
#define rtr rt<<1|1
#define bug printf("*******");
struct LINE {
int x, y1, y2, flag;
} line[maxn];
int cmp(LINE a, LINE b) {
if (a.x == b.x) return a.flag > b.flag;
return a.x < b.x;
}
struct node {
int l, r, line, cover;
int m, lbd, rbd;
} tree[maxn << ];
int y[maxn];
void build(int l, int r, int rt) {
tree[rt].l = l, tree[rt].r = r;
tree[rt].cover = tree[rt].m = tree[rt].line = ;
tree[rt].lbd = tree[rt].rbd = ;
if (r - l > ) {
int m = (l + r) >> ;
build(l, m, rtl);
build(m, r, rtr);
}
}
void update_line(int rt) {
if (tree[rt].cover > ) {
tree[rt].lbd = tree[rt].rbd = tree[rt].line = ;
} else if (tree[rt].r - tree[rt].l == ) {
tree[rt].lbd = tree[rt].rbd = tree[rt].line = ;
} else {
tree[rt].lbd = tree[rtl].lbd;
tree[rt].rbd = tree[rtr].rbd;
tree[rt].line = tree[rtl].line + tree[rtr].line - tree[rtl].rbd * tree[rtr].lbd;
}
}
void update_m(int rt) {
if (tree[rt].cover > ) tree[rt].m = y[tree[rt].r] - y[tree[rt].l];
else if (tree[rt].r - tree[rt].l == ) tree[rt].m = ;
else tree[rt].m = tree[rtl].m + tree[rtr].m; }
void add(int l, int r, int rt) {
if (y[tree[rt].l] >= l && y[tree[rt].r] <= r) tree[rt].cover++;
else if (tree[rt].r - tree[rt].l == ) return ;
else {
int m = (tree[rt].l + tree[rt].r) >> ;
if (r <= y[m]) add(l, r, rtl);
else if (l > y[m]) add(l, r, rtr);
else {
add(l, y[m], rtl);
add(y[m], r, rtr);
}
}
update_line(rt);
update_m(rt);
}
void del(int l, int r, int rt) {
if (y[tree[rt].l] >= l && y[tree[rt].r] <= r) tree[rt].cover--;
else if (tree[rt].r - tree[rt].l == ) return;
else {
int m = (tree[rt].l + tree[rt].r) >> ;
if (r <= y[m]) del(l, r, rtl);
else if (l > y[m]) del(l, r, rtr);
else {
del(l, y[m], rtl);
del(y[m], r, rtr);
}
}
update_line(rt);
update_m(rt);
}
int main() {
int n, cnt = ;
scanf("%d", &n);
for (int i = ; i < n ; i++) {
int x1, y1, x2, y2;
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
line[cnt].x = x1;
line[cnt].y1 = y1;
line[cnt].y2 = y2;
line[cnt].flag = ;
y[cnt++] = y1;
line[cnt].x = x2;
line[cnt].y1 = y1;
line[cnt].y2 = y2;
line[cnt].flag = ;
y[cnt++] = y2;
}
sort(y, y + cnt);
sort(line, line + cnt, cmp);
int len = unique(y, y + cnt) - y;
build(, len - , );
int ans = , now_m = , now_line = ;
for (int i = ; i < cnt ; i++) {
if (line[i].flag) add(line[i].y1, line[i].y2, );
else del(line[i].y1, line[i].y2, );
if (i >= ) ans += * now_line * (line[i].x - line[i - ].x);
ans += abs(tree[].m - now_m);
now_m = tree[].m;
now_line = tree[].line;
}
printf("%d\n", ans);
return ;
}

Picture POJ - 1177 (线段树-扫描线)的更多相关文章

  1. Picture POJ - 1177 线段树+离散化+扫描线 求交叉图像周长

    参考  https://www.cnblogs.com/null00/archive/2012/04/22/2464876.html #include <stdio.h> #include ...

  2. POJ - 1177 线段树

    POJ - 1177 扫描线 这道题也算是一道扫描线的经典题目了. 只不过这道题是算周长,非常有意思的一道题.我们已经知道了,一般求面积并,是如何求的,现在我们要把扫描线进行改造一下,使得能算周长. ...

  3. POJ 3277 线段树+扫描线

    题意: 思路: 线段树求矩形面积的并...同 POJ 1151 //By SiriusRen #include <cstdio> #include <algorithm> us ...

  4. POJ 1151 线段树+扫描线

    题意:求矩形面积的并 思路: 注意是[l,mid][mid,r] 这是真正的线段了 就当扫描线模板使吧~ //By SiriusRen #include <cmath> #include ...

  5. POJ 1151 线段树+扫描线(计算矩形面积并)

    前一篇博客有了讲解就不再叙述了 #include<cstdio> #include<cstring> #include<cmath> #include<ios ...

  6. 51nod 1206 Picture 矩形周长求并 | 线段树 扫描线

    51nod 1206 Picture 矩形周长求并 | 线段树 扫描线 #include <cstdio> #include <cmath> #include <cstr ...

  7. 线段树 扫描线 L - Atlantis HDU - 1542 M - City Horizon POJ - 3277 N - Paint the Wall HDU - 1543

    学习博客推荐——线段树+扫描线(有关扫描线的理解) 我觉得要注意的几点 1 我的模板线段树的叶子节点存的都是 x[L]~x[L+1] 2 如果没有必要这个lazy 标志是可以不下传的 也就省了一个pu ...

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

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

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

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

  10. hdu1828 Picture(线段树+扫描线+矩形周长)

    看这篇博客前可以看一下扫描线求面积:线段树扫描线(一.Atlantis HDU - 1542(覆盖面积) 二.覆盖的面积 HDU - 1255(重叠两次的面积))  解法一·:两次扫描线 如图我们可以 ...

随机推荐

  1. Qt+opencv:读取、显示图像

    GitHub:点击下载完整代码 本文主要是使用Qt与opencv将图像进行显示在QT界面上. 程序运行后的界面如下所示: (由于只有打开图像之后,才能对图像进行翻转,所以程序设置为读取图像成功之后才能 ...

  2. ionic 获取input的值

    1.参数传递法 例子:获取input框内容 这里有个独特的地方,直接在input处使用 #定义参数的name值,注意在ts中参数的类型 在html页面中 <ion-input type=&quo ...

  3. Paper Reading - Show, Attend and Tell: Neural Image Caption Generation with Visual Attention ( ICML 2015 )

    Link of the Paper: https://arxiv.org/pdf/1502.03044.pdf Main Points: Encoder-Decoder Framework: Enco ...

  4. 关闭Tomcat进程 一条语句(必看)

    写在开始 MAC系统下进行JAVA研发,经常遇到的一个问题就是杀死异常Tomcat 通常都是用两条指令,先查询出Tomcat占用的进程,再kill掉该进程, 其实有一种联合语句的方式可以一条语句直接关 ...

  5. wpa_supplicant下行接口浅析

    wpa_supplicant通过socket通信机制实现下行接口,与内核进行通信,获取信息或下发命令. 以下摘自http://blog.csdn.net/fxfzz/article/details/6 ...

  6. Java学习个人备忘录之多态

    对象的多态性 class 动物 {} class 猫 extends 动物 {} class 狗 extends 动物 {} 猫 x = new 猫();//意思是建立本类的对象 new 猫(),并通 ...

  7. Android开发 使用 adb logcat 显示 Android 日志

    作者 : 万境绝尘  转载请著名出处 eclipse 自带的 LogCat 工具太垃圾了, 开始用 adb logcat 在终端查看日志; 1. 解析 adb logcat 的帮助信息 在命令行中输入 ...

  8. iOS-AFNetworking与ASIHTTPRequest的区别

    一.底层实现 1.AFN的底层实现基于OC的NSURLConnection和NSURLSession  2.ASI的底层实现基于纯C语言的CFNetwork框架  3.因为NSURLConnectio ...

  9. OSG学习:转动的小汽车示例

    由于只是简单的示例,所以小汽车的模型也比较简单,是由简单的几何体组成. 代码如下: #include <osg\ShapeDrawable> #include <osg\Animat ...

  10. ZOJ 2072 K-Recursive Survival

    https://vjudge.net/contest/67836#problem/K n people numbered 1 to n around a circle, we eliminate ev ...