HDU1828线段树(扫描线)
Picture |
| Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) |
| Total Submission(s): 12 Accepted Submission(s): 10 |
|
Problem Description
A number of rectangular posters, photographs and other pictures of the same shape are pasted on a wall. Their sides are all vertical or horizontal. Each rectangle can be partially or totally covered by the others. The length of the boundary of the union of all rectangles is called the perimeter.
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
Your program is to read from standard input. The first line contains the number of rectangles pasted on the wall. In each of the subsequent lines, one can find the integer coordinates of the lower left vertex and the upper right vertex of each rectangle. The values of those coordinates are given as ordered pairs consisting of an x-coordinate followed by a y-coordinate.
0 <= number of rectangles < 5000 Please process to the end of file. |
|
Output
Your program is to write to standard output. The output must contain a single line with a non-negative integer which corresponds to the perimeter for the input rectangles.
|
|
Sample Input
7 |
|
Sample Output
228 |
|
Source
IOI 1998
|
题意:
给出n个矩形的右下和左上角的坐标,问这n个矩形组成的图形的边长
代码:
参考博客
http://blog.csdn.net/u013480600/article/details/22548393
http://blog.csdn.net/u012860063/article/details/43163949
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn=;
int cnt[maxn*],segnum[maxn*],sum[maxn*],pre[maxn*],suf[maxn*];
struct node{
int l,r,h,d;
node(){}
node(int a,int b,int c,int d):l(a),r(b),h(c),d(d){}
bool operator < (node&p){
if(h==p.h) return d>p.d;
return h<p.h;
}
}nodes[maxn];
void pushup(int l,int r,int rt){
if(cnt[rt]){//是下底边
segnum[rt]=;
pre[rt]=suf[rt]=;
sum[rt]=r-l+;
}
else if(l==r)//是叶子
segnum[rt]=sum[rt]=pre[rt]=suf[rt]=;
else{
segnum[rt]=segnum[rt<<]+segnum[rt<<|];
if(suf[rt<<]&&pre[rt<<|]) segnum[rt]-=;//有竖边重合
sum[rt]=sum[rt<<]+sum[rt<<|];
pre[rt]=pre[rt<<];//用两个儿子的两头更新父亲的两头
suf[rt]=suf[rt<<|];
}
}
void build(int l,int r,int rt){//本题中可以不用build递归,直接memset数组就行
cnt[rt]=;suf[rt]=;pre[rt]=;segnum[rt]=;sum[rt]=;
if(l==r) return;
int m=(l+r)>>;
build(l,m,rt<<);
build(m+,r,rt<<|);
}
void update(int L,int R,int c,int l,int r,int rt){
if(L<=l&&R>=r){
cnt[rt]+=c;
pushup(l,r,rt);
return;
}
int m=(l+r)>>;
if(L<=m) update(L,R,c,l,m,rt<<);
if(R>m) update(L,R,c,m+,r,rt<<|);
pushup(l,r,rt);
}
int main()
{
int t,x1,x2,y1,y2;
while(scanf("%d",&t)==){
int lbd=-,rbd=,m=;
while(t--){
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
lbd=min(lbd,x1);
rbd=max(rbd,x2);
nodes[m++]=node(x1,x2,y1,);
nodes[m++]=node(x1,x2,y2,-);
}
build(lbd,rbd-,);
sort(nodes,nodes+m);
int ans=,last=;
for(int i=;i<m;i++){
if(nodes[i].l<=nodes[i].r-) //这个判断要有!
update(nodes[i].l,nodes[i].r-,nodes[i].d,lbd,rbd-,);
ans+=abs(sum[]-last);//算横向边
last=sum[];//更新前一个边
if(i!=m-)//算纵向边
ans+=segnum[]*(nodes[i+].h-nodes[i].h);
}
printf("%d\n",ans);
}
return ;
}
HDU1828线段树(扫描线)的更多相关文章
- hdu1828(线段树+扫描线)
又知道了线段树的一种用法,除了单点更新,区间更新,还有这种在一段线段上标号但不往下推. 真是神奇 hdu1828 #include <iostream> #include <stdi ...
- hdu1828 线段树扫描线求矩形面积的周长
题意: 给你n个矩形,问你这n个矩形所围成的图形的周长是多少. 思路: 线段树的扫描线简单应用,这个题目我用的方法比较笨,就是扫描两次,上下扫描,求出多边形的上下边长和,然后同 ...
- hdu1828 Picture(线段树+扫描线+矩形周长)
看这篇博客前可以看一下扫描线求面积:线段树扫描线(一.Atlantis HDU - 1542(覆盖面积) 二.覆盖的面积 HDU - 1255(重叠两次的面积)) 解法一·:两次扫描线 如图我们可以 ...
- HDU 1828“Picture”(线段树+扫描线求矩形周长并)
传送门 •参考资料 [1]:算法总结:[线段树+扫描线]&矩形覆盖求面积/周长问题(HDU 1542/HDU 1828) •题意 给你 n 个矩形,求矩形并的周长: •题解1(两次扫描线) 周 ...
- 线段树扫描线(一、Atlantis HDU - 1542(覆盖面积) 二、覆盖的面积 HDU - 1255(重叠两次的面积))
扫描线求周长: hdu1828 Picture(线段树+扫描线+矩形周长) 参考链接:https://blog.csdn.net/konghhhhh/java/article/details/7823 ...
- 【Codeforces720D】Slalom 线段树 + 扫描线 (优化DP)
D. Slalom time limit per test:2 seconds memory limit per test:256 megabytes input:standard input out ...
- Codeforces VK CUP 2015 D. Closest Equals(线段树+扫描线)
题目链接:http://codeforces.com/contest/522/problem/D 题目大意: 给你一个长度为n的序列,然后有m次查询,每次查询输入一个区间[li,lj],对于每一个查 ...
- 【POJ-2482】Stars in your window 线段树 + 扫描线
Stars in Your Window Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 11706 Accepted: ...
- HDU 4419 Colourful Rectangle --离散化+线段树扫描线
题意: 有三种颜色的矩形n个,不同颜色的矩形重叠会生成不同的颜色,总共有R,G,B,RG,RB,GB,RGB 7种颜色,问7种颜色每种颜色的面积. 解法: 很容易想到线段树扫描线求矩形面积并,但是如何 ...
- BZOJ-3228 棋盘控制 线段树+扫描线+鬼畜毒瘤
3228: [Sdoi2008]棋盘控制 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 23 Solved: 9 [Submit][Status][D ...
随机推荐
- JQuery文本框验证
<" CODEPAGE="936"%><!--#include file="conncon.asp"--><!--#in ...
- Thunder团队第六周 - Scrum会7
Scrum会议7 小组名称:Thunder 项目名称:i阅app Scrum Master:杨梓瑞 工作照片: 参会成员: 王航:http://www.cnblogs.com/wangh013/ 李传 ...
- 往Matlab中添加工具包
使用Matlab过程中,常常会缺少一些函数包导致无法运行,会显示未定义函数. 假如我要用sigshift( ) 这个移位函数,但Matlab中没有,就会提示错误:未定义函数或变量 'sigshift' ...
- iOS- 简单说说iOS移动客户端SQLite3的基本使用
1.为什么要使用SQLite3? •大量数据需要存储 •管理数据,存储数据 SQLite是一种关系型数据库(也是目前移动客户端的主流数据库) 2.SQLite3的几种存储类型 a.NU ...
- Scala快速入门-基础
HelloWorld 从HelloWorld开始,使用scala IDE编辑器. 新建scala project 新建scala object 编写HelloWorld run as scala ap ...
- C#,Winform 文件的导入导出 File
1.导入 导入对话框:OpenFileDialog private void sbtnsb_Click(object sender, EventArgs e) { try { OpenFileDial ...
- 用glob()函数返回目录下的子文件以及子目录
glob() 函数返回匹配指定模式的文件名或目录 相对于readdir()和opendir()来说,使用glob()函数会方便很多 代码1: <?php function getfilename ...
- windows默认TEMP环境
留着是为了等出问题的时候能找着改回来 Administrator 的用户变量 TEMP %USERPROFILE%\AppData\Local\Temp TMP %USERPRO ...
- pyHeatMap生成热力图
库链接:https://pypi.org/project/pyheatmap/ 现在的linux系统默认都是安装好的py环境,直接用pip进行热力库安装 pip install pyheatmap 或 ...
- shit antd & Merry Christmas bug
shit antd & Merry Christmas bug https://github.com/ant-design/ant-design/issues/13098 antd 玩大了? ...

