HDU 1828 扫描线(矩形周长并)
Picture
Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3310 Accepted Submission(s): 1723
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.
0 <= number of rectangles < 5000
All coordinates are in the range [-10000,10000] and any existing rectangle has a positive area.
Please process to the end of file.
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <vector>
#include <queue>
#include <cmath>
#include <set>
using namespace std; #define N 5005
#define ll root<<1
#define rr root<<1|1
#define mid (a[root].l+a[root].r)/2 int max(int x,int y){return x>y?x:y;}
int min(int x,int y){return x<y?x:y;}
int abs(int x,int y){return x<?-x:x;} struct node{
int l, r;
int sum;
int ysum;
int val;
bool lv, rv;
}a[N*]; struct Line{
int x1, x2, y;
int val;
Line(){}
Line(int a,int b,int c,int d){
x1=a;
x2=b;
y=c;
val=d;
}
}line[N*]; bool cmp(Line a,Line b){
return a.y<b.y;
}
int n, m;
int xx[N*]; int b_s(int key){
int l=, r=m;
while(l<=r){
int mm=(l+r)/;
if(xx[mm]==key) return mm;
else if(xx[mm]>key) r=mm-;
else if(xx[mm]<key) l=mm+;
}
} void build(int l,int r,int root){
a[root].l=l;
a[root].r=r;
a[root].ysum=a[root].sum=a[root].val=;
a[root].lv=a[root].rv=false;
if(l==r) return;
build(l,mid,ll);
build(mid+,r,rr);
} void up(int root){
if(a[root].val){
a[root].sum=xx[a[root].r+]-xx[a[root].l];
a[root].lv=a[root].rv=true;
a[root].ysum=;
}
else if(a[root].l==a[root].r) {
a[root].lv=a[root].rv=false;
a[root].ysum=a[root].sum=;
}
else{
a[root].sum=a[ll].sum+a[rr].sum;
a[root].lv=a[ll].lv;
a[root].rv=a[rr].rv;
a[root].ysum=a[ll].ysum+a[rr].ysum;
if(a[rr].lv&&a[ll].rv) a[root].ysum-=;
}
} void update(int l,int r,int val,int root){
if(a[root].l==l&&a[root].r==r){
a[root].val+=val;
up(root);
return;
}
if(l>=a[rr].l) update(l,r,val,rr);
else if(r<=a[ll].r) update(l,r,val,ll);
else{
update(l,mid,val,ll);
update(mid+,r,val,rr);
}
up(root);
} main()
{
int i, j, k;
int x1, y1, x2, y2;
int kase=;
while(scanf("%d",&n)==&&n){
m=;k=;
for(i=;i<n;i++){
scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
line[k++]=Line(x1,x2,y1,);
line[k++]=Line(x1,x2,y2,-);
xx[m++]=x1;xx[m++]=x2;
}
sort(xx+,xx+m);
m=unique(xx+,xx+m)-xx-;
sort(line,line+k,cmp);
build(,m,);
int ans=;
int pre=;
for(i=;i<k-;i++){
update(b_s(line[i].x1),b_s(line[i].x2)-,line[i].val,);
ans+=abs(a[].sum-pre)+(line[i+].y-line[i].y)*a[].ysum;
pre=a[].sum;
}
update(b_s(line[k-].x1),b_s(line[k-].x2)-,line[k-].val,);
ans+=abs(a[].sum-pre);
printf("%d\n",ans);
}
}
HDU 1828 扫描线(矩形周长并)的更多相关文章
- hdu 1828 Picture(线段树扫描线矩形周长并)
线段树扫描线矩形周长并 #include <iostream> #include <cstdio> #include <algorithm> #include &l ...
- 扫描线矩形周长的并 POJ1177
//扫描线矩形周长的并 POJ1177 // 我是按x轴 #include <iostream> #include <cstdio> #include <cstdlib& ...
- hdu1828 Picture(线段树+扫描线+矩形周长)
看这篇博客前可以看一下扫描线求面积:线段树扫描线(一.Atlantis HDU - 1542(覆盖面积) 二.覆盖的面积 HDU - 1255(重叠两次的面积)) 解法一·:两次扫描线 如图我们可以 ...
- HDU 1828 Picture(线段树扫描线求周长)
Picture Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Su ...
- HDU 1828“Picture”(线段树+扫描线求矩形周长并)
传送门 •参考资料 [1]:算法总结:[线段树+扫描线]&矩形覆盖求面积/周长问题(HDU 1542/HDU 1828) •题意 给你 n 个矩形,求矩形并的周长: •题解1(两次扫描线) 周 ...
- HDU 1828 / POJ 1177 Picture (线段树扫描线,求矩阵并的周长,经典题)
做这道题之前,建议先做POJ 1151 Atlantis,经典的扫描线求矩阵的面积并 参考连接: http://www.cnblogs.com/scau20110726/archive/2013/0 ...
- hdu 1828 线段树扫描线(周长)
Picture Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Sub ...
- HDU 1828 / POJ 1177 Picture --线段树求矩形周长并
题意:给n个矩形,求矩形周长并 解法:跟求矩形面积并差不多,不过线段树节点记录的为: len: 此区间线段长度 cover: 此区间是否被整个覆盖 lmark,rmark: 此区间左右端点是否被覆盖 ...
- HDU 1828 Picture(长方形的周长和)
HDU 1828 Picture 题目链接 题意:给定n个矩形,输出矩形周长并 思路:利用线段树去维护,分别从4个方向扫一次,每次多一段的时候,就查询该段未被覆盖的区间长度,然后周长就加上这个长度,4 ...
随机推荐
- bootstrap学习笔记<十一>(导航条)
基础导航条.样式:class="navbar navbar-default",属性:role="navigation" <div class=" ...
- 2014 Multi-University Training Contest 4
1006 hdu4902 #include <iostream> #include<stdio.h> #include<vector> #include<qu ...
- JS获取用户控件中的子控件Id
用户控件 <asp:HiddenField ID="hfGradeId" runat="server" /> <asp:HiddenField ...
- C++——输入、输出和文件
一.C++输入和输出概述 1.1.流和缓冲区 C++程序把输入和输出看作字节流.输入时,程序从输入流中抽取字节:输出时,程序将字节插入到输出流中.对于面相文本的程序,每个字节代表一个字符,更通俗地说, ...
- 转!!MAC和PHY的区别
一块以太网网卡包括OSI(开方系统互联)模型的两个层,物理层和数据链路层.物理层定义了数据传送与接收所需要的电与光信号.线路状态.时钟基准.数据编码和电路等,并向数据链路层设备提供标准接口.数据链路层 ...
- icp算法基本思想
Icp基本思想参考资料:http://www.cnblogs.com/jian-li/articles/4945676.html ,包括点-点,点-面的各种icp变种 Icp算法就是两个点云X.Y之间 ...
- association ,collection
mybatis 出现这个错误Error creating document instance. Cause: org.xml.sax.SAXParseException; lineNumber: 2 ...
- FireFox背景亮度修改
安装stylish 输入:body{filter: brightness(80%);}
- Scrum 项目5.0
1.团队成员完成自己认领的任务. 2.燃尽图:理解.设计并画出本次Sprint的燃尽图的理想线.参考图6. 3.每日立会更新任务板上任务完成情况.燃尽图的实际线,分析项目进度是否在正轨. 每天的 ...
- Python中一些内建函数及os等模块的用法
len(obj) # 求长度:obj可以是str.list等对象 split(str, num) # str-分割符,默认空格: ...