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 ...
随机推荐
- SSH:远程登陆
SSH用于计算机之间的加密登录的前提是公钥为真,所以存在中间人攻击中间人攻击:与https协议不同,SSH协议的公钥是没有CA公证的,当对公钥的请求被中间截获时,中间人可以发出伪造公钥干坏事而不被识破 ...
- Python3 Tkinter-Pack
1.创建 from tkinter import * root=Tk() print(root.pack_slaves()) Label(root,text='pack').pack() print( ...
- 拷贝构造函数 & 拷贝赋值运算符
一.拷贝构造函数 1. 形式 class A { public: // ... A(const A &); // 拷贝构造函数 }; 2. 合成拷贝构造函数 编译器总会为我们合成一个拷贝构造函 ...
- Fafa and the Gates(模拟)
Two neighboring kingdoms decided to build a wall between them with some gates to enable the citizens ...
- c#程序的config文件问题
1.vshost.exe.config和app.config两个文件可不要,但exe.config文件不可少. 2.但是app.config最好也要修改了,每次重新生成程序的时候.exe.cmonfi ...
- C语言 命令行参数 函数指针 gdb调试
. 作者 : 万境绝尘 转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/21551397 | http://www.hanshul ...
- Unity3d学习日记(一)
闲来无事开始自学unity3d,发现还挺容易入门的,添加资源文件以及用c#编写脚本都很方便. 前面在Unity官方教程上自学了一段时间,跟着教程写了个space_shooter的小游戏,虽然游 ...
- idea导出jar包
在File->Project Structure->Artifacts,如图: 然后: 点击Apply,OK. 跳出去就可以看到多了META-INF文件夹: 然后build项目,就可以看 ...
- 再看RCU
从昨天晚上开始,我就立志要把RCU拿下,昨晚加今天早上看了RCU的东西,太细节的原理我就不扣了,放弃,知道RCU是怎么用的就可以了,赶紧看文件系统中dcache的管理了. 说说RCU,RCU其实是很简 ...
- HTML5+ API 学习
HTML5+ API 模块整理 API Reference 模块 中文 模块介绍 Accelerometer 加速计 管理设备加速度传感器,用于获取设备加速度信息,包括x(屏幕水平方向).y(垂直屏幕 ...

