HDU1828 Picture 线段树+扫描线模板题
Picture
Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 6332 Accepted Submission(s): 2951
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.
-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
代码如下
#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <stack>
#include <queue>
#include <cstdio>
#include <cctype>
#include <bitset>
#include <string>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <functional>
#define fuck(x) cout<<"["<<x<<"]";
#define FIN freopen("input.txt","r",stdin);
#define FOUT freopen("output.txt","w+",stdout);
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int maxn = 1e5+;
struct node1{
int l,r;
int cover;
int len;
int lbt,rbt;
int segnum;
}st[maxn<<];
struct node2{
int x,y1,y2;
int flag;
}edge[maxn];
int Y[maxn];
void build(int root,int l,int r){
st[root].l=l;
st[root].r=r;
st[root].cover=st[root].len=;
st[root].lbt=st[root].rbt=;
st[root].segnum=;
if(r-l==) return;
int mid=(l+r+)/;
build(root<<,l,mid);
build(root<<|,mid,r);
} void update(int root){
if(st[root].cover>){
st[root].len=Y[st[root].r]-Y[st[root].l];
st[root].lbt=st[root].rbt=;
st[root].segnum=;
}else if(st[root].r-st[root].l==){
st[root].len=;
st[root].lbt=st[root].rbt=;
st[root].segnum=;
}else{
st[root].len=st[root<<].len+st[root<<|].len;
st[root].lbt=st[root<<].lbt;
st[root].rbt=st[root<<|].rbt;
st[root].segnum=st[root<<].segnum+st[root<<|].segnum-st[root<<].rbt*st[root<<|].lbt;
}
}
void update(int root,int val,int y1,int y2){
if(y1<=Y[st[root].l]&&Y[st[root].r]<=y2){
st[root].cover+=val;
}else{
int mid=(st[root].l+st[root].r+)/;
if(y1<Y[mid]) update(root<<,val,y1,y2);
if(y2>Y[mid]) update(root<<|,val,y1,y2);
}
update(root);
}
bool cmp(node2 a,node2 b){
if(a.x==b.x) return a.y1<b.y1;
return a.x<b.x;
}
int main(){
#ifndef ONLINE_JUDGE
FIN
#endif int n;
while(scanf("%d",&n) !=EOF){
if(n==) printf("0\n");
int x1,x2,y1,y2;
for(int i=;i<n;i++){
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
edge[i<<].x=x1;
edge[i<<].y1=y1;
edge[i<<].y2=y2;
edge[i<<].flag=;
Y[i<<]=y1;
edge[i<<|].x=x2;
edge[i<<|].y1=y1;
edge[i<<|].y2=y2;
edge[i<<|].flag=-;
Y[i<<|]=y2;
}
sort(Y,Y+*n);
sort(edge,edge+*n,cmp);
int cnt=;
for(int i=;i<*n;i++){
if(Y[i]!=Y[i+]) Y[cnt++]=Y[i];
}
Y[cnt++]=Y[*n-];
build(,,cnt-);
int ans=;
int lastlen=;
for(int i=;i<*n-;i++){
update(,edge[i].flag,edge[i].y1,edge[i].y2);
ans+=*st[].segnum*(edge[i+].x-edge[i].x);
ans+=abs(st[].len-lastlen);
lastlen=st[].len;
}
ans+=(edge[*n-].y2-edge[*n-].y1);
printf("%d\n",ans);
}
return ;
}
HDU1828 Picture 线段树+扫描线模板题的更多相关文章
- hdu1828 Picture(线段树+扫描线+矩形周长)
看这篇博客前可以看一下扫描线求面积:线段树扫描线(一.Atlantis HDU - 1542(覆盖面积) 二.覆盖的面积 HDU - 1255(重叠两次的面积)) 解法一·:两次扫描线 如图我们可以 ...
- Zeratul的完美区间(线段树||RMQ模板题)
原题大意:原题链接 给定元素无重复数组,查询给定区间内元素是否连续 解体思路:由于无重复元素,所以如果区间内元素连续,则该区间内的最大值和最小值之差应该等于区间长度(r-l) 解法一:线段树(模板题) ...
- POJ 1177 Picture(线段树 扫描线 离散化 求矩形并面积)
题目原网址:http://poj.org/problem?id=1177 题目中文翻译: 解题思路: 总体思路: 1.沿X轴离散化建树 2.按Y值从小到大排序平行与X轴的边,然后顺序处理 如果遇到矩形 ...
- poj 1177 Picture (线段树 扫描线 离散化 矩形周长并)
题目链接 题意:给出n个矩形,每个矩形给左下 和 右上的坐标,求围成的周长的长度. 分析: 首先感谢大神的博客,最近做题经常看大神的博客:http://www.cnblogs.com/kuangbin ...
- poj 1177 --- Picture(线段树+扫描线 求矩形并的周长)
题目链接 Description A number of rectangular posters, photographs and other pictures of the same shape a ...
- HDU 1828 Picture (线段树:扫描线周长)
依然是扫描线,只不过是求所有矩形覆盖之后形成的图形的周长. 容易发现,扫描线中的某一条横边对答案的贡献. 其实就是 加上/去掉这条边之前的答案 和 加上/去掉这条边之后的答案 之差的绝对值 然后横着竖 ...
- Luogu1856 [USACO5.5]矩形周长Picture (线段树扫描线)
对于横轴,加上与上一次扫描的差值:对于竖轴,加上高度差与区间内不相交线段\(*2\)的积: 难点在pushdown,注意维护覆盖关系.再就注意负数 #include <iostream> ...
- HDU 1828 Picture (线段树+扫描线)(周长并)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1828 给你n个矩形,让你求出总的周长. 类似面积并,面积并是扫描一次,周长并是扫描了两次,x轴一次,y ...
- 线段树扫描线(一、Atlantis HDU - 1542(覆盖面积) 二、覆盖的面积 HDU - 1255(重叠两次的面积))
扫描线求周长: hdu1828 Picture(线段树+扫描线+矩形周长) 参考链接:https://blog.csdn.net/konghhhhh/java/article/details/7823 ...
随机推荐
- ruby Dir类
类方法 1. Dir[pat] Dir::glob( pat) 返回一个数组,包含与指定的通配符模式 pat 匹配的文件名: * - 匹配包含 null 字符串的任意字符串 ** - 递归地匹配 ...
- Shoot the Bullet(ZOJ3229)(有源汇上下界最大流)
描述 ensokyo is a world which exists quietly beside ours, separated by a mystical border. It is a utop ...
- 【转】iOS库 .a与.framework区别
转自:http://blog.csdn.net/lvxiangan/article/details/43115131 一.什么是库? 库是共享程序代码的方式,一般分为静态库和动态库. 二.静态库与动态 ...
- 8.Mongodb备份与恢复
1.备份 语法 mongodump -h dbhost -d dbname -o dbdirectory -h:服务器地址,也可以指定端口号 -d:需要备份的数据库名称 -o:备份的数据存放位置,此目 ...
- Java面试题集合
1.Java的HashMap是如何工作的? HashMap是一个针对数据结构的键值,每个键都会有相应的值,关键是识别这样的值. HashMap 基于 hashing 原理,我们通过 put ()和 g ...
- 读取hbase数据到mysql
先写一个自己的MyRecordWriter类 extends RecordWriter package calllog; import java.io.IOException; import java ...
- Hackerrank - [Algo] Matrix Rotation
https://www.hackerrank.com/challenges/matrix-rotation-algo 又是一道耗了两小时以上的题,做完了才想起来,这不就是几年前在POJ上做过的一个同类 ...
- Android Google Maps 监听地图缩放
接上篇.http://www.cnblogs.com/maomishen/p/3556297.html 由于公司项目要求,需要对google map监听地图的缩放(zoom)来进行一些操作. 但是在网 ...
- Linux-Shell脚本编程-学习-4-Shell编程-操作数字-加减乘除计算
对于任何一种编程语言都很重要的特性就是操作数字的能力,遗憾的是,对于shell脚本来说,这个过程比较麻烦,在shell脚本中有两种途径来进行数学运算操作. 1.expr 最开始的时候,shell提供了 ...
- 第八篇Python基本数据类型之列表、元组与字典
列表 写在最前,必须要会的:append(),extend(),insert(),索引,切片,循环 list 是一个类,是个对象 列表用 方括号[]括起来的,[]内以逗号分割每个元素,列表中的元素可 ...