poj 1177 Picture (线段树 扫描线 离散化 矩形周长并)
题意:给出n个矩形,每个矩形给左下 和 右上的坐标,求围成的周长的长度。
分析:
首先感谢大神的博客,最近做题经常看大神的博客:http://www.cnblogs.com/kuangbin/
沿x轴离散化。和之前的矩阵面积并有点像。
但是一定要去重,否则会错
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#define LL __int64
#define lson l, mid, 2*rt
#define rson mid+1, r, 2*rt+1
const int maxn = +;
using namespace std;
int n, x[maxn];
struct node
{
int l, r, cnt;
int lf, rf;
int num, c; //num是分支的个数,即当前的x段有多少段,可以想象一段是对应两个竖边的。
bool lc, rc; //表示左端是否覆盖,和右端是否覆盖,用来判断x段是否练成一块了
}tr[maxn*];
struct Line
{
int y, x1, x2, f;
}line[maxn];
bool cmp(Line a, Line b)
{
return a.y < b.y;
}
void build(int l, int r, int rt)
{
tr[rt].l = l; tr[rt].r = r;
tr[rt].lf = x[l]; tr[rt].rf = x[r];
tr[rt].cnt = ; tr[rt].num = ;
tr[rt].c = ;
tr[rt].lc = tr[rt].rc = false;
if(tr[rt].l+ == tr[rt].r) return;
int mid = (l+r)/;
build(l, mid, *rt);
build(mid, r, *rt+);
}
void calen(int rt)
{
if(tr[rt].c>)
{
tr[rt].cnt = tr[rt].rf-tr[rt].lf;
tr[rt].num = ;
tr[rt].lc = tr[rt].rc = true; //这整个一块都覆盖了,左右端点自然也覆盖
return;
}
if(tr[rt].l+ == tr[rt].r)
{
tr[rt].cnt = tr[rt].num = ;
tr[rt].lc = tr[rt].rc = false;
}
else
{
tr[rt].cnt = tr[*rt].cnt+tr[*rt+].cnt;
tr[rt].lc = tr[*rt].lc; tr[rt].rc = tr[*rt+].rc;//自己这块没有覆盖,看一下子节点是否有覆盖
tr[rt].num = tr[*rt].num+tr[*rt+].num;
if(tr[*rt].rc && tr[*rt+].lc) tr[rt].num --; //如果当前这个节点的子节点左的右
//覆盖和右的左覆盖说明中间已经练成一片了,所以分支-1
}
}
void update(int rt, Line e)
{
if(tr[rt].lf==e.x1 && tr[rt].rf==e.x2)
{
tr[rt].c += e.f;
calen(rt);
return;
}
if(e.x2<=tr[*rt].rf) update(*rt, e);
else if(e.x1>=tr[*rt+].lf) update(*rt+, e);
else
{
Line tmp;
tmp = e;
tmp.x2 = tr[*rt].rf;
update(*rt, tmp);
tmp = e;
tmp.x1 = tr[*rt+].lf;
update(*rt+, tmp);
}
calen(rt);
}
int main()
{
int i, t, ans, pre;
int x1, x2, y1, y2;
while(~scanf("%d", &n))
{
t = ; ans = ; pre = ;
for(i = ; i < n; i++)
{
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
line[t].x1 = x1; line[t].x2 = x2;
line[t].y = y1; line[t].f = ;
x[t++] = x1;
line[t].x1 = x1; line[t].x2 = x2;
line[t].y = y2; line[t].f = -;
x[t++] = x2;
}
sort(x, x+t);
sort(line, line+t, cmp);
int y = unique(x, x+t)-x; //去重
build(, y-, ); for(i = ; i < t-; i++)
{
update(, line[i]);
ans += tr[].num**(line[i+].y-line[i].y); //竖线的长度
ans += abs(tr[].cnt-pre); //加上 新增的横线 或者 是减少的横线
pre = tr[].cnt;
}
update(, line[i]);
ans += abs(tr[].cnt-pre);
printf("%d\n", ans);
}
return ;
}
poj 1177 Picture (线段树 扫描线 离散化 矩形周长并)的更多相关文章
- POJ 1177 Picture(线段树 扫描线 离散化 求矩形并面积)
题目原网址:http://poj.org/problem?id=1177 题目中文翻译: 解题思路: 总体思路: 1.沿X轴离散化建树 2.按Y值从小到大排序平行与X轴的边,然后顺序处理 如果遇到矩形 ...
- poj 1177 --- Picture(线段树+扫描线 求矩形并的周长)
题目链接 Description A number of rectangular posters, photographs and other pictures of the same shape a ...
- HDU 1828“Picture”(线段树+扫描线求矩形周长并)
传送门 •参考资料 [1]:算法总结:[线段树+扫描线]&矩形覆盖求面积/周长问题(HDU 1542/HDU 1828) •题意 给你 n 个矩形,求矩形并的周长: •题解1(两次扫描线) 周 ...
- POJ-1151-Atlantis(线段树+扫描线+离散化)[矩形面积并]
题意:求矩形面积并 分析:使用线段树+扫描线...因为坐标是浮点数的,因此还需要离散化! 把矩形分成两条边,上边和下边,对横轴建树,然后从下到上扫描上去,用col表示该区间有多少个下边,sum代表该区 ...
- HDU 1828 / POJ 1177 Picture --线段树求矩形周长并
题意:给n个矩形,求矩形周长并 解法:跟求矩形面积并差不多,不过线段树节点记录的为: len: 此区间线段长度 cover: 此区间是否被整个覆盖 lmark,rmark: 此区间左右端点是否被覆盖 ...
- hdu 4419 线段树 扫描线 离散化 矩形面积
//离散化 + 扫描线 + 线段树 //这个线段树跟平常不太一样的地方在于记录了区间两个信息,len[i]表示颜色为i的被覆盖的长度为len[i], num[i]表示颜色i 『完全』覆盖了该区间几层. ...
- Picture POJ - 1177 (线段树-扫描线)
A number of rectangular posters, photographs and other pictures of the same shape are pasted on a wa ...
- POJ 1177 Picture(线段树周长并)
描述 A number of rectangular posters, photographs and other pictures of the same shape are pasted on ...
- hdu 1542&&poj 1151 Atlantis[线段树+扫描线求矩形面积的并]
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
随机推荐
- net windows Kafka
net windows Kafka 安装与使用入门(入门笔记) 完整解决方案请参考: Setting Up and Running Apache Kafka on Windows OS 在环境搭建 ...
- 常用的机器学习&数据挖掘知识点【转】
转自: [基础]常用的机器学习&数据挖掘知识点 Basis(基础): MSE(Mean Square Error 均方误差),LMS(LeastMean Square 最小均方),LSM(Le ...
- JavaScript string array 数组
Array类可以如下定义: var aValues = new Array(); 如果预先知道数组的长度,可以用参数传递长度 var aValues = new Array(20); -------- ...
- Matlab与科学计算的基本运算
各种允许的比较关系 >, >=, <, <=, ==,~=, find(), all(), any() 例:>> A=[1,2,3;4,5,6;7,8,0]A = ...
- [转载]JS中如何定义全局变量
三种方法 1.在js的function外定义一个变量 var name='测试'; function XX(){ alert(name); } 2.不使用var,直接给定义变量,隐式的声 ...
- JavaScript高级---组合模式设计
一.设计模式 javascript里面给我们提供了很多种设计模式: 工厂.桥.组合.门面.适配器.装饰者.享元.代理.观察者.命令.责任链 在前面我们实现了工厂模式和桥模式 工厂模式 : 核心:为了生 ...
- running android lint has encountered a problem
最近写学习android编程的的时候,每次保存.java文件的时候,总会跳出如下错误 解决:
- DataGridView之行的展开与收缩
很多数据都有父节点与子节点,我们希望单击父节点的时候可以展开父节点下的子节点数据. 比如一个医院科室表,有父科室与子科室,点击父科室后,在父科室下面可以展现该科室下的所有子科室. 我们来说一下在Dat ...
- poj 3620 Avoid The Lakes(广搜,简单)
题目 找最大的一片湖的面积,4便有1边相连算相连,4角不算. runtime error 有一种可能是 数组开的太小,越界了 #define _CRT_SECURE_NO_WARNINGS #incl ...
- 1009-2的N次方
描述 编程精确计算2的N次方.(N是介于100和1000之间的整数). 输入 正整数N (100≤N≤1000) 输出 2的N次方 样例输入 200 样例输出 16069380442589902755 ...