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(重叠两次的面积)) 解法一·:两次扫描线 如图我们可以 ...
随机推荐
- (Python爬虫05)完善的爬虫学习大纲
- JAVA中 "\" 和 "/" 的区别
1.在java中路径一般用”/” 2.linux.unix中的路径一般用”/” 3.windows中的路径一般用”\” 所以在java中写windows路径一般用”/”,或用“\”将”\”转义一下(& ...
- django request bug
bug描述:django请求request接收数据时,如果参数中包含分号时,会导致分号后面的消息丢失. 比如前台js调用代码 $.post('/get_params', { "A" ...
- svn升级(mac)
原文链接:http://www.jianshu.com/p/c81712ecccb8 升级前 svn版本1.7.20 升级之后 1.9.2 步骤: 1. 下载最新版svn,链接:http://www. ...
- svn服务器 备份,迁移,部署方案
这次做业务迁移,要从一个云厂商迁移到某云厂商,之前每天到全备svn排到用场了,需要搭建一个全新到svn服务并要做迁移,并实现我们开发机到时时代码同步 一.svn备份有很多种,优劣都不同,百度可查,我采 ...
- JAVA mysql数据库 配置
mysql 版本 5.7 数据库连接版本 <!--MySql--><dependency> <groupId>mysql</groupId> <a ...
- spring学习(一)——控制反转简单例子
spring框架是一个开源的轻量级的基于IOC与AOP核心技术的容器框架,主要是解决企业的复杂操作实现. 那IOC与AOP,到底如何解释呢,在看spring视频中,两个专业术语一定必须要懂得. IOC ...
- iOS开发解决页面滑动返回跟scrollView左右划冲突
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithG ...
- Css入门课程 Css文本样式
文字是网页的非常基础的内容,文本的样式设置也是非常重要的 1 字体大小 font-size:绝对大小单位和相对大小单位,绝对大小单位有cm,mm in(厘米,毫米,英寸)等,这是大小不随屏幕分辨率大小 ...
- PokeCats开发者日志(十)
现在是PokeCats游戏开发的第三十三天的中午,收到了中国版权保护中心软件登记部发来的受理通知书. 上易版权看一眼,貌似离拿证不远了. 想一想还有点小激动呢!