poj 1177 --- Picture(线段树+扫描线 求矩形并的周长)
Description
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
Source
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
const int N=;
struct Line{
int x,y1,y2;
int flag;
bool operator<(const Line s)
{
if(x==s.x) return flag>s.flag;
return x<s.x;
}
}line[N*]; struct Tree
{
int l,r;
bool lf,rf; ///左右边界点是否被覆盖;
int cover_len;
int cover_num;
int num; ///矩形数目;
}tr[N*]; vector<int>v; void build(int l,int r,int i)
{
tr[i].l=l; tr[i].r=r;
tr[i].cover_len=;
tr[i].cover_num=;
tr[i].num=;
tr[i].lf=tr[i].rf=false;
if(l+==r) return ;
int mid=(l+r)>>;
build(l,mid,i<<);
build(mid,r,i<<|);
}
void process(int i)
{
if(tr[i].cover_num>)
{
tr[i].cover_len=v[tr[i].r]-v[tr[i].l];
tr[i].lf=tr[i].rf=true;
tr[i].num=;
return ;
}
if(tr[i].l+==tr[i].r)
{
tr[i].cover_len=;
tr[i].num=;
tr[i].lf=tr[i].rf=false;
return ;
}
int ls=(i<<);
int rs=(i<<|);
tr[i].cover_len=tr[ls].cover_len+tr[rs].cover_len;
tr[i].num=tr[ls].num + tr[rs].num - (tr[ls].rf & tr[rs].lf);
tr[i].lf=tr[ls].lf; tr[i].rf=tr[rs].rf;
}
void update(int i,Line t)
{
if(t.y1<=v[tr[i].l] && v[tr[i].r]<=t.y2)
{
tr[i].cover_num+=t.flag;
process(i);
return ;
}
int mid=(tr[i].l+tr[i].r)>>;
if(t.y1<v[mid]) update(i<<,t);
if(t.y2>v[mid]) update(i<<|,t);
process(i);
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
v.clear();
for(int i=;i<n;i++)
{
int x1,y1,x2,y2;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
line[i*].x=x1; line[i*].y1=y1; line[i*].y2=y2; line[i*].flag=;
line[i*+].x=x2; line[i*+].y1=y1; line[i*+].y2=y2; line[i*+].flag=-;
v.push_back(y1);
v.push_back(y2);
}
sort(line,line+*n);
sort(v.begin(),v.end());
int num=unique(v.begin(),v.end())-v.begin(); build(,num-,);
int ans=,len=;
for(int i=;i<*n;i++)
{
if(i>) ans+=tr[].num**(line[i].x-line[i-].x);
update(,line[i]);
ans+=abs(tr[].cover_len-len);
len=tr[].cover_len;
}
printf("%d\n",ans);
}
return ;
}
poj 1177 --- Picture(线段树+扫描线 求矩形并的周长)的更多相关文章
- poj 1177 Picture (线段树 扫描线 离散化 矩形周长并)
题目链接 题意:给出n个矩形,每个矩形给左下 和 右上的坐标,求围成的周长的长度. 分析: 首先感谢大神的博客,最近做题经常看大神的博客:http://www.cnblogs.com/kuangbin ...
- POJ 1177 Picture(线段树 扫描线 离散化 求矩形并面积)
题目原网址:http://poj.org/problem?id=1177 题目中文翻译: 解题思路: 总体思路: 1.沿X轴离散化建树 2.按Y值从小到大排序平行与X轴的边,然后顺序处理 如果遇到矩形 ...
- hdu1828 线段树扫描线求矩形面积的周长
题意: 给你n个矩形,问你这n个矩形所围成的图形的周长是多少. 思路: 线段树的扫描线简单应用,这个题目我用的方法比较笨,就是扫描两次,上下扫描,求出多边形的上下边长和,然后同 ...
- hdu 1542&&poj 1151 Atlantis[线段树+扫描线求矩形面积的并]
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- HDU 1828“Picture”(线段树+扫描线求矩形周长并)
传送门 •参考资料 [1]:算法总结:[线段树+扫描线]&矩形覆盖求面积/周长问题(HDU 1542/HDU 1828) •题意 给你 n 个矩形,求矩形并的周长: •题解1(两次扫描线) 周 ...
- hdu1542 线段树扫描线求矩形面积的并
题意: 给你n个正方形,求出他们的所占面积有多大,重叠的部分只能算一次. 思路: 自己的第一道线段树扫描线题目,至于扫描线,最近会写一个总结,现在就不直接在这里写了,说下我的方 ...
- HDU 1828 / POJ 1177 Picture --线段树求矩形周长并
题意:给n个矩形,求矩形周长并 解法:跟求矩形面积并差不多,不过线段树节点记录的为: len: 此区间线段长度 cover: 此区间是否被整个覆盖 lmark,rmark: 此区间左右端点是否被覆盖 ...
- UVA-11983-Weird Advertisement(线段树+扫描线)[求矩形覆盖K次以上的面积]
题意: 求矩形覆盖K次以上的面积 分析: k很小,可以开K颗线段树,用sum[rt][i]来保存覆盖i次的区间和,K次以上全算K次 // File Name: 11983.cpp // Author: ...
- 2015 UESTC 数据结构专题E题 秋实大哥与家 线段树扫描线求矩形面积交
E - 秋实大哥与家 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/contest/show/59 De ...
随机推荐
- python 子进程 subpocess 的使用方法简单介绍
python的子进程嘛,就是利用python打开一个子进程(当然像是一句废话),但是可能和我们理解的不太一样. 一:如何理解? 我们可能的理解:多开一个进程运行某个python函数(如果只想实现这个功 ...
- 五、Pyqt5事件、信号和槽
PyQt中提供了两种针对事件处理的机制:一种是事件,另一种则是信号和槽. 一.事件 事件处理在PyQt中是比较底层的,常用的事件有键盘事件.鼠标事件.拖放事件.滚轮事件.定时事件.焦点事件.进入和离开 ...
- vb编程中的is是什么意思??
在select case 语句中可以使用关系运算符大于>小于<等于=等关系运算符,需要用关键字IS和TO.用个例子来说明:Private Sub Command1_Click()Dim a ...
- servlet运行原理
- Js高级程序设计~读书笔记
1.函数-函数声明和函数表达式 解析器在向执行环境加载数据时,函数声明和函数表达式的对待不同. 解析器会率先执行函数声明,将会在任何使用到它的地方前加载, 而对于函数表达式,只会在执行到的时候去加载: ...
- 87、代码适配IphoneX
一.APP在iphoneX运行后不能占满,上下都有多余的边 解决方法:把旧的image.xcassets中的LaunchImage删掉,重新创建并在Images.xcassets中为iPhone X添 ...
- 15. Life Cycle of the Products 产品的生命周期
15. Life Cycle of the Products 产品的生命周期 (1) We can see how the product life cycle works by looking at ...
- web页面font-family显示
font-family属性很简单,直接写在css或style样式中即可. 如: font-family: "Microsoft YaHei"; 但是如果希望电脑能正确的显示我们设置 ...
- liunx_second_day
liunx-基本权限 1.文件和目录权限的区别 A.文件的权限:所有者,所属组,其他人 rwx,读,写,执行,没有权限就是- 第一组rwx:文件所有者的权限 第二组rwx:文件所属组的权限 第三组rw ...
- 从今天开始慢慢阅读java9源码决心的声明。
我从很早的时候就好奇java的源码了,因为有使用者就有制作者. 在校期间使用了java两年多的我却不知道java里面的任何东西. 这个寒假前我无意之间看到了java9出现的新闻,网上查询到原来源码就隐 ...