题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1828

给你n个矩形,让你求出总的周长。

类似面积并,面积并是扫描一次,周长并是扫描了两次,x轴一次,y轴一次。每次加起来的无非都是新加的边(flag为1)或者是新减的边(flag为-1),即加起来的是此时的总长度(T[1].val)减去上一次扫到的总长度(last)的绝对值(T[1].val - last)。(注意用c++提交,g++会wa)

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 2e4 + ;
struct data {
int l , r , h , flag;
bool operator <(const data& cmp) const {
return h < cmp.h;
}
}x[MAXN] , y[MAXN];
struct segtree {
int l , r , val , add;
}T[MAXN << ]; int f(int a) {
return (a > ? a : -a);
} void build(int p , int l , int r) {
int mid = (l + r) >> ;
T[p].l = l , T[p].r = r , T[p].add = T[p].val = ;
if(r - l == ) {
return ;
}
build(p << , l , mid);
build((p << )| , mid , r);
} void pushup(int p) {
if(T[p].add) {
T[p].val = T[p].r - T[p].l;
}
else if(T[p].r - T[p].l == ) {
T[p].val = ;
}
else {
T[p].val = T[p << ].val + T[(p << )|].val;
}
} void updata(int p , int l , int r , int add) {
int mid = (T[p].l + T[p].r) >> ;
if(l == T[p].l && T[p].r == r) {
T[p].add += add;
pushup(p);
return ;
}
if(r <= mid) {
updata(p << , l , r , add);
}
else if(l >= mid) {
updata((p << )| , l , r , add);
}
else {
updata(p << , l , mid , add);
updata((p << )| , mid , r , add);
}
pushup(p);
} int main()
{
int n , x1 , x2 , y1 , y2;
while(~scanf("%d" , &n)) {
for(int i = ; i < n ; i++) {
scanf("%d %d %d %d" , &x1 , &y1 , &x2 , &y2);
x1 += 1e4 , x2 += 1e4 , y1 += 1e4 , y2 += 1e4;
if(x1 > x2)
swap(x1 , x2);
if(y1 > y2)
swap(y1 , y2);
int ls = i<< , rs = (i<<)|;
x[ls].l = x1 , x[ls].r = x2 , x[ls].h = y1 , x[ls].flag = ;
x[rs].l = x1 , x[rs].r = x2 , x[rs].h = y2 , x[rs].flag = -;
y[ls].l = y1 , y[ls].r = y2 , y[ls].h = x1 , y[ls].flag = ;
y[rs].l = y1 , y[rs].r = y2 , y[rs].h = x2 , y[rs].flag = -;
}
sort(x , x + n * );
sort(y , y + n * );
build( , , 2e4);
int res = , last = ;
for(int i = ; i < * n ; i++) {
updata( , x[i].l , x[i].r , x[i].flag);
res += f(last - T[].val);
last = T[].val;
}
for(int i = ; i < * n ; i++) {
updata( , y[i].l , y[i].r , y[i].flag);
res += f(last - T[].val);
last = T[].val;
}
printf("%d\n" , res);
}
}

HDU 1828 Picture (线段树+扫描线)(周长并)的更多相关文章

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

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

  2. POJ 1177/HDU 1828 picture 线段树+离散化+扫描线 轮廓周长计算

    求n个图矩形放下来,有的重合有些重合一部分有些没重合,求最后总的不规则图型的轮廓长度. 我的做法是对x进行一遍扫描线,再对y做一遍同样的扫描线,相加即可.因为最后的轮廓必定是由不重合的线段长度组成的, ...

  3. hdu 1828 Picture(线段树 || 普通hash标记)

    http://acm.hdu.edu.cn/showproblem.php?pid=1828 Picture Time Limit: 6000/2000 MS (Java/Others)    Mem ...

  4. hdu 1828 Picture(线段树轮廓线)

    Picture Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Sub ...

  5. hdu 1828 线段树扫描线(周长)

    Picture Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Sub ...

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

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

  7. HDU 1828 Picture(长方形的周长和)

    HDU 1828 Picture 题目链接 题意:给定n个矩形,输出矩形周长并 思路:利用线段树去维护,分别从4个方向扫一次,每次多一段的时候,就查询该段未被覆盖的区间长度,然后周长就加上这个长度,4 ...

  8. HDU 1542 - Atlantis - [线段树+扫描线]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1542 Time Limit: 2000/1000 MS (Java/Others) Memory Li ...

  9. 覆盖的面积 HDU - 1255 (线段树-扫描线)模板提

    给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. Input输入数据的第一行是一个正整数T(1<=T<=100),代表测试数据的数量.每个测试数据的第一行是一个正整数N(1& ...

随机推荐

  1. How can I add a new user as sudoer using the command line?

    Two ways to use sudo command for a standard user account: First, If you want to use sudo command for ...

  2. LA 2889 (找规律) Palindrome Numbers

    输出第n个回文数. 规律就是一位和两位的回文数各有9个,三位四位的回文数各有90个,以此类推. 给出n,可以先判定一下第n个回文数的位数,然后后面也不难推,但是有很多细节需要注意. #include ...

  3. BNU 4188 Superprime Rib【BFS】

    题意:给出n,输出n位超级质数,超级质数的定义为“依次去掉右边一位后仍然为质数的数” 因为一个n位质数去掉右边一位数之后仍然为质数,说明它是由n-1位超级质数演变而来的, 同理,n-1位超级质数也由n ...

  4. [源代码] - C#代码搜索器 - 续

    在前文 [源代码] - C#代码搜索器 中我开发了一个代码搜索器. 我对其做的最后改动是将索引保存到磁盘中, 以备今后使用. 如今, 我在工作中又接到一项新任务: 有一个大项目, 其中10个负责数据访 ...

  5. hdu 4604 Deque(最长不下降子序列)

    从后向前对已搜点做两遍LIS(最长不下降子序列),分别求出已搜点的最长递增.递减子序列长度.这样一直搜到第一个点,就得到了整个序列的最长递增.递减子序列的长度,即最长递减子序列在前,最长递增子序列在后 ...

  6. Oracle AWR报告自动生成并ftp脚本

    脚本主要由以下几个部分组成: awr.sql 用来在sqlplus 中执行的脚本,该脚本从网上直接找的. awr.sh 用来调用sqlplus来生成awr报告. ftp.sh 用来打包压缩每天生成的a ...

  7. c# 利用反射动态给实体类对象赋值

    转:http://blog.sina.com.cn/s/blog_659a572b0100xp5s.html 例子如下 using System; using System.Collections.G ...

  8. SQL之50个常用的SQL语句

    50个常用的sql语句 Student(S#,Sname,Sage,Ssex) 学生表 Course(C#,Cname,T#) 课程表 SC(S#,C#,score) 成绩表 Teacher(T#,T ...

  9. Android中TabHost嵌套TabHost

    在嵌套TabHost时,先后遇到了以下情况: 问题1:内部TabHos无显示,只显示了其中的一个Activity: 解决:按下文比对主子TabHos的布局文件和java文件并修改: 问题2:如上所做后 ...

  10. HDU 5765 Bonds 巧妙状压暴力

    题意:给一个20个点无向连通图,求每条边被多少个极小割集包括 分析:极小割集是边的集合,很显然可以知道,极小割集恰好吧原图分成两部分(这个如果不明白可以用反证法) 然后就是奉上官方题解:http:// ...