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 ...
随机推荐
- [转载] C++ 程序员快过来围观:非常实用全面的 C++ 资源
原文: http://codecloud.net/c-plus-plus-resource-2983.html 绝对是c++开发者的福音啊, 必须推荐. 这次的资源涉及到了标准库.Web应用框架.人工 ...
- poj3384Feng Shui(半平面交)
链接 将边长向内推进r,明显这样把第一个圆的圆心放在新的边长是肯定是最优的,与原本边相切,然后再找新多边上的最远的两点即为两圆心. #include <iostream> #include ...
- Object Pascal 控制语句
控制语句 1.常量声明语句常量在声明时就被赋予了一个值,在程序执行过程中是不可改变的. 格式 const 常量名 :数据类型 = 值 下面的例子声明了3 个常量: const Pi = 3.14159 ...
- svn设置提交忽略某些文件或文件夹
在svn客户端,想设置忽略提交.class文件,通过 properties > New > Other 添加一个忽略的属性,,还是不行:部分屏蔽了,部分class还是在列表中 再次参考了一 ...
- ssh批量登录并执行命令(python实现)
局域网内有一百多台电脑,全部都是linux操作系统,所有电脑配置相同,系统完全相同(包括用户名和密码),ip地址是自动分配的.现在有个任务是在这些电脑上执行某些命令,者说进行某些操作,比如安装某些软件 ...
- Spring MVC 之请求处理方法可接收参数(三)
请求处理方法可接收参数 今天学习了前三个方法. 1.作用域对象2.单个表单提交数据3.表单数据封装的Bean对象 首先创建一个实体对象. package com.cy.springannotation ...
- PHP 获取服务器详细信息【转】
碰到此问题,做下记录 获取系统类型及版本号: php_uname() (例:Windows NT COMPUTER 5.1 b ...
- JSP lifecycle - with servlet
编译阶段: servlet容器编译servlet源文件,生成servlet类 初始化阶段: 加载与JSP对应的servlet类,创建其实例,并调用它的初始化方法 执行阶段: 调用与JSP对应的serv ...
- 串行通讯之.NET SerialPort
第1章串行通讯之.NET SerialPort 2 1 枚举串口 2 2 打开/关闭串口 2 3 写数据 3 3.1 写二进制数据 3 3.2 写文本数据 4 4 ...
- TWaver HTML5 (2D)----数据元素
概述 数据元素是数据模型的基本要素,用于描述图形网元,业务网元,或者纯数据.TWaver HTML5中所有数据元素都继承自twaver.Data.为不同功能的需求,预定义了三类数据类型:twaver. ...