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(重叠两次的面积)) 解法一·:两次扫描线 如图我们可以 ...
随机推荐
- 某即时通信工具与RMS结合
某客户内部使用及时通信工具与RMS相结合,如果客户使用了海外版Office 365E3可以直接在手机端使用Office app打开. 如果客户没有使用海外版Office 365E3的版本,需要结合本地 ...
- Ubuntu—安装并运行sublime
step1 到官网看看 https://www.sublimetext.com/3 step2 根据版本选择,我的是32位的 step3 ubuntu终端安装 (1)切换目录 -$ cd /opt ...
- Solidity中的基本类型转换
Solidity中的基本类型转换(十四)|入门系列 2017/4/29 posted in Solidity入门系列 点击查看原文,获得优化的排版. 隐式转换 如果一个运算符能支持不同类型.编译器会隐 ...
- “Hello world!”团队—团队选题展示(视频展示说明)
本次博客的主要内容基本分为以下两方面: 一.视频截图展示 二.视频简要说明 博客内容展示: 视频截图1: 简要说明:这是组长在视频前期简要介绍我们这款游戏项目的内容.从可行性和需求市场方面进行了简要阐 ...
- finecms
finecms地址 还不错的国内CMS http://www.dayrui.com/doc/246.html
- JavaScript数组自定义属性
我们可以以json键值对的形式自定义属性. 首先定义一个JS数组JSarray. 然后按json键值对的形式进行赋值. 最后在控制台显示结果. 代码如下: var JSarray = new Arra ...
- Css入门课程 Css基础
html css javascript三者关系 html是网页内容的载体 css是网页内容的表现,外观控制 javascript是网页逻辑处理和行为控制 css相对于html标签属性的优势 css简化 ...
- WE团队团队汇总
WE团队目录 一.博客汇总 团队展示 选题报告 二.文档汇总 选题报告
- Python的time,datetime,string相互转换
#把datetime转成字符串 def datetime_toString(dt): return dt.strftime("%Y-%m-%d-%H") #把字符串转成dateti ...
- 手把手教你写Kafka Streams程序
本文从以下四个方面手把手教你写Kafka Streams程序: 一. 设置Maven项目 二. 编写第一个Streams应用程序:Pipe 三. 编写第二个Streams应用程序:Line Split ...