Picture POJ - 1177 (线段树-扫描线)
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
0 <= number of rectangles < 5000
All coordinates are in the range [-10000,10000] and any existing rectangle has a positive area.
Output
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 (线段树-扫描线)的更多相关文章
- Picture POJ - 1177 线段树+离散化+扫描线 求交叉图像周长
参考 https://www.cnblogs.com/null00/archive/2012/04/22/2464876.html #include <stdio.h> #include ...
- POJ - 1177 线段树
POJ - 1177 扫描线 这道题也算是一道扫描线的经典题目了. 只不过这道题是算周长,非常有意思的一道题.我们已经知道了,一般求面积并,是如何求的,现在我们要把扫描线进行改造一下,使得能算周长. ...
- POJ 3277 线段树+扫描线
题意: 思路: 线段树求矩形面积的并...同 POJ 1151 //By SiriusRen #include <cstdio> #include <algorithm> us ...
- POJ 1151 线段树+扫描线
题意:求矩形面积的并 思路: 注意是[l,mid][mid,r] 这是真正的线段了 就当扫描线模板使吧~ //By SiriusRen #include <cmath> #include ...
- POJ 1151 线段树+扫描线(计算矩形面积并)
前一篇博客有了讲解就不再叙述了 #include<cstdio> #include<cstring> #include<cmath> #include<ios ...
- 51nod 1206 Picture 矩形周长求并 | 线段树 扫描线
51nod 1206 Picture 矩形周长求并 | 线段树 扫描线 #include <cstdio> #include <cmath> #include <cstr ...
- 线段树 扫描线 L - Atlantis HDU - 1542 M - City Horizon POJ - 3277 N - Paint the Wall HDU - 1543
学习博客推荐——线段树+扫描线(有关扫描线的理解) 我觉得要注意的几点 1 我的模板线段树的叶子节点存的都是 x[L]~x[L+1] 2 如果没有必要这个lazy 标志是可以不下传的 也就省了一个pu ...
- hdu 1828 Picture(线段树扫描线矩形周长并)
线段树扫描线矩形周长并 #include <iostream> #include <cstdio> #include <algorithm> #include &l ...
- HDU 1828“Picture”(线段树+扫描线求矩形周长并)
传送门 •参考资料 [1]:算法总结:[线段树+扫描线]&矩形覆盖求面积/周长问题(HDU 1542/HDU 1828) •题意 给你 n 个矩形,求矩形并的周长: •题解1(两次扫描线) 周 ...
- hdu1828 Picture(线段树+扫描线+矩形周长)
看这篇博客前可以看一下扫描线求面积:线段树扫描线(一.Atlantis HDU - 1542(覆盖面积) 二.覆盖的面积 HDU - 1255(重叠两次的面积)) 解法一·:两次扫描线 如图我们可以 ...
随机推荐
- 【WXS数据类型】Object
Object 是一种无序的键值对. 属性: 名称 值类型 说明 [Object].constructor [String] 返回值为“Object”,表示类型的结构字符串 方法: 原型:[Object ...
- ntp服务:实现时间同步
一. 引言 目前的项目为分布式系统,采用dubbo+zookeepe,排查BUG,发现各个服务器的时间不一致,遂网上查找资源,使得时间保持一致. 二. 步骤 1)以第一台服务器为“服务端”,其他台服务 ...
- Huffuman树
问题描述 Huffman树在编码中有着广泛的应用.在这里,我们只关心Huffman树的构造过程. 给出一列数{pi}={p0, p1, …, pn-1},用这列数构造Huffman树的过程如下: 1. ...
- About Dynamic Programming
Main Point: Dynamic Programming = Divide + Remember + Guess 1. Divide the key is to find the subprob ...
- 福大软工1816:Alpha(9/10)
Alpha 冲刺 (9/10) 队名:第三视角 组长博客链接 本次作业链接 团队部分 团队燃尽图 工作情况汇报 张扬(组长) 过去两天完成了哪些任务: 文字/口头描述: 1.完善通过父子进程调用wxp ...
- 团队作业7——第二次项目冲刺-Beta版本项目计划
上一个阶段的总结: 在Alpha阶段,我们小组已近完成了大部分的功能要求,小组的每一个成员都发挥了自己的用处.经过了这么久的磨合,小组的成员之间越来越默契,相信在接下来的合作中,我们的开发速度会越来越 ...
- lintcode-163-不同的二叉查找树
163-不同的二叉查找树 给出 n,问由 1...n 为节点组成的不同的二叉查找树有多少种? 样例 给出n = 3,有5种不同形态的二叉查找树: 标签 卡特兰数 动态规划 思路 参考博客http:// ...
- iOS- 网络请求的两种常用方式【GET & POST】的区别
GET和POST 网络请求的两种常用方式的实现[GET & POST] –GET的语义是获取指定URL上的资源 –将数据按照variable=value的形式,添加到action所指向的URL ...
- iOS-【UIDynamic-UIKit动力学】
如果看不到图片 可以尝试更换浏览器(推荐Safari ) 0.了解 •Dynamic Animator:动画者,为动力学元素提供物理学相关的能力及动画,同时为这些元素提供相关的上下文,是动力学元素与底 ...
- 华为oj----iNOC产品部-杨辉三角的变形 .
此题提供三种方法,第一种,一开始就能想到的,设置一个足够大的数组存储生成的杨辉三角,然后进行判断就行,此方法参见:华为oj iNOC产品部-杨辉三角的变形 另一种方法是采用递归: 三角形的每行的个数为 ...