Picture

Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 6332    Accepted Submission(s): 2951

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 
All coordinates are in the range [-10000,10000] and any existing rectangle has a positive area.

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
-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
 
Sample Output
228

代码如下

#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 线段树+扫描线模板题的更多相关文章

  1. hdu1828 Picture(线段树+扫描线+矩形周长)

    看这篇博客前可以看一下扫描线求面积:线段树扫描线(一.Atlantis HDU - 1542(覆盖面积) 二.覆盖的面积 HDU - 1255(重叠两次的面积))  解法一·:两次扫描线 如图我们可以 ...

  2. Zeratul的完美区间(线段树||RMQ模板题)

    原题大意:原题链接 给定元素无重复数组,查询给定区间内元素是否连续 解体思路:由于无重复元素,所以如果区间内元素连续,则该区间内的最大值和最小值之差应该等于区间长度(r-l) 解法一:线段树(模板题) ...

  3. POJ 1177 Picture(线段树 扫描线 离散化 求矩形并面积)

    题目原网址:http://poj.org/problem?id=1177 题目中文翻译: 解题思路: 总体思路: 1.沿X轴离散化建树 2.按Y值从小到大排序平行与X轴的边,然后顺序处理 如果遇到矩形 ...

  4. poj 1177 Picture (线段树 扫描线 离散化 矩形周长并)

    题目链接 题意:给出n个矩形,每个矩形给左下 和 右上的坐标,求围成的周长的长度. 分析: 首先感谢大神的博客,最近做题经常看大神的博客:http://www.cnblogs.com/kuangbin ...

  5. poj 1177 --- Picture(线段树+扫描线 求矩形并的周长)

    题目链接 Description A number of rectangular posters, photographs and other pictures of the same shape a ...

  6. HDU 1828 Picture (线段树:扫描线周长)

    依然是扫描线,只不过是求所有矩形覆盖之后形成的图形的周长. 容易发现,扫描线中的某一条横边对答案的贡献. 其实就是 加上/去掉这条边之前的答案 和 加上/去掉这条边之后的答案 之差的绝对值 然后横着竖 ...

  7. Luogu1856 [USACO5.5]矩形周长Picture (线段树扫描线)

    对于横轴,加上与上一次扫描的差值:对于竖轴,加上高度差与区间内不相交线段\(*2\)的积: 难点在pushdown,注意维护覆盖关系.再就注意负数 #include <iostream> ...

  8. HDU 1828 Picture (线段树+扫描线)(周长并)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1828 给你n个矩形,让你求出总的周长. 类似面积并,面积并是扫描一次,周长并是扫描了两次,x轴一次,y ...

  9. 线段树扫描线(一、Atlantis HDU - 1542(覆盖面积) 二、覆盖的面积 HDU - 1255(重叠两次的面积))

    扫描线求周长: hdu1828 Picture(线段树+扫描线+矩形周长) 参考链接:https://blog.csdn.net/konghhhhh/java/article/details/7823 ...

随机推荐

  1. ruby Dir类

    类方法 1. Dir[pat]    Dir::glob( pat) 返回一个数组,包含与指定的通配符模式 pat 匹配的文件名: * - 匹配包含 null 字符串的任意字符串 ** - 递归地匹配 ...

  2. Shoot the Bullet(ZOJ3229)(有源汇上下界最大流)

    描述 ensokyo is a world which exists quietly beside ours, separated by a mystical border. It is a utop ...

  3. 【转】iOS库 .a与.framework区别

    转自:http://blog.csdn.net/lvxiangan/article/details/43115131 一.什么是库? 库是共享程序代码的方式,一般分为静态库和动态库. 二.静态库与动态 ...

  4. 8.Mongodb备份与恢复

    1.备份 语法 mongodump -h dbhost -d dbname -o dbdirectory -h:服务器地址,也可以指定端口号 -d:需要备份的数据库名称 -o:备份的数据存放位置,此目 ...

  5. Java面试题集合

    1.Java的HashMap是如何工作的? HashMap是一个针对数据结构的键值,每个键都会有相应的值,关键是识别这样的值. HashMap 基于 hashing 原理,我们通过 put ()和 g ...

  6. 读取hbase数据到mysql

    先写一个自己的MyRecordWriter类 extends RecordWriter package calllog; import java.io.IOException; import java ...

  7. Hackerrank - [Algo] Matrix Rotation

    https://www.hackerrank.com/challenges/matrix-rotation-algo 又是一道耗了两小时以上的题,做完了才想起来,这不就是几年前在POJ上做过的一个同类 ...

  8. Android Google Maps 监听地图缩放

    接上篇.http://www.cnblogs.com/maomishen/p/3556297.html 由于公司项目要求,需要对google map监听地图的缩放(zoom)来进行一些操作. 但是在网 ...

  9. Linux-Shell脚本编程-学习-4-Shell编程-操作数字-加减乘除计算

    对于任何一种编程语言都很重要的特性就是操作数字的能力,遗憾的是,对于shell脚本来说,这个过程比较麻烦,在shell脚本中有两种途径来进行数学运算操作. 1.expr 最开始的时候,shell提供了 ...

  10. 第八篇Python基本数据类型之列表、元组与字典

    列表 写在最前,必须要会的:append(),extend(),insert(),索引,切片,循环 list  是一个类,是个对象 列表用 方括号[]括起来的,[]内以逗号分割每个元素,列表中的元素可 ...