依然是扫描线,只不过是求所有矩形覆盖之后形成的图形的周长。

容易发现,扫描线中的某一条横边对答案的贡献。

其实就是 加上/去掉这条边之前的答案 和 加上/去掉这条边之后的答案 之差的绝对值

然后横着竖着都做一遍就行了

 #include <cstdio>
#include <cstring>
#include <algorithm>
#define N 10010
#define ll long long
using namespace std; int n,sz;
int a[N],cnt[N<<],sum[N<<];
struct SQU{
int a1,b1,a2,b2;
}q[N];
struct node{
int l,r,la,ra,h,f;
}sc[N];
int cmp1(node s1,node s2){
if(s1.h!=s2.h) return s1.h<s2.h;
else return s1.f>s2.f;
}
void pushup(int l,int r,int rt)
{
if(cnt[rt]>) sum[rt]=a[r+]-a[l];
else if(l==r) sum[rt]=;
else sum[rt]=sum[rt<<]+sum[rt<<|];
}
void update(int L,int R,int l,int r,int rt,int w)
{
if(L<=l&&r<=R)
{
cnt[rt]+=w;
pushup(l,r,rt);
return;
}
int mid=(l+r)>>;
if(L<=mid) update(L,R,l,mid,rt<<,w);
if(R>mid) update(L,R,mid+,r,rt<<|,w);
pushup(l,r,rt);
}
void clr()
{
memset(a,,sizeof(a));
memset(sc,,sizeof(sc));
memset(cnt,,sizeof(cnt));
memset(sum,,sizeof(sum));
}
int solvex()
{
int ans=,lst=;
for(int i=;i<=n;i++)
{
a[*i-]=q[i].a1,a[*i]=q[i].a2;
sc[*i-].l=q[i].a1,sc[*i].l=q[i].a1;
sc[*i-].r=q[i].a2,sc[*i].r=q[i].a2;
sc[*i-].h=q[i].b1,sc[*i].h=q[i].b2;
sc[*i-].f=,sc[*i].f=-;
}
sort(a+,a+*n+);
sz=unique(a+,a+*n+)-(a+);
sort(sc+,sc+*n+,cmp1);
for(int i=;i<=*n;i++)
{
int la=lower_bound(a+,a+sz+,sc[i].l)-a;
int ra=lower_bound(a+,a+sz+,sc[i].r)-a;
lst=sum[];
update(la,ra-,,sz,,sc[i].f);
ans+=abs(sum[]-lst);
}
return ans;
}
int solvey()
{
int ans=,lst=;
for(int i=;i<=n;i++)
{
a[*i-]=q[i].b1,a[*i]=q[i].b2;
sc[*i-].l=q[i].b1,sc[*i].l=q[i].b1;
sc[*i-].r=q[i].b2,sc[*i].r=q[i].b2;
sc[*i-].h=q[i].a1,sc[*i].h=q[i].a2;
sc[*i-].f=,sc[*i].f=-;
}
sort(a+,a+*n+);
sz=unique(a+,a+*n+)-(a+);
sort(sc+,sc+*n+,cmp1);
for(int i=;i<=*n;i++)
{
int la=lower_bound(a+,a+sz+,sc[i].l)-a;
int ra=lower_bound(a+,a+sz+,sc[i].r)-a;
lst=sum[];
update(la,ra-,,sz,,sc[i].f);
ans+=abs(sum[]-lst);
}
return ans;
} int main()
{
//freopen("data.in","r",stdin);
scanf("%d",&n);
for(int i=;i<=n;i++)
scanf("%d%d%d%d",&q[i].a1,&q[i].b1,&q[i].a2,&q[i].b2);
int ret=;
ret+=solvex();
clr();
ret+=solvey();
printf("%d\n",ret);
return ;
}

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

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

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

  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. vncserve安装与使用

    vncserver安装与配置 1.1.Centos安装 yum install tigervnc-server yum groupinstall "X Window System" ...

  2. js:Array对象常用方法介绍

    前言 在js中,数组作为一个特殊的对象.是我们常用的数据格式.今天就来梳理一下常用的数组方法. 1.基础 几种基础的就简单介绍一下:创建数组 var arr1 = new Array(); //括号可 ...

  3. Windows使用docker打开新窗口error解决办法

    环境 win7 Error: error during connect: Get http://%2F%2F.%2Fpipe%2Fdocker_engine/v1.26/containers/json ...

  4. python第一周:python初识、流程控制

    编译性语言:在将源代码编译完毕生成一个可执行文件后才能运行 解释性语言:在代码的运行期间进行编译 动态类型语言:在运行期间才去做数据检查的语言,也就是说在使用动态类型语言时不用指定数据类型 静态类型语 ...

  5. gcc 源代码分析-前端篇2

    2. 对ID及保留字的处理    在c语言中,系统预留了非常多keyword.也被称为保留字,比方表示数据类型的int,short,char,控制分支运行的if,then等. 不论什么keyword, ...

  6. wordpress迁移以及遇到的一些问题[mysql备份导入导出][固定链接404]

    总的问题有两个,一是apache的配置,二是mysql的导出和导入.以及迁移后遇到的一些问题解决过程和方法. A机器为老server.B为新server,A机器使用Appserv,B使用wmap,在配 ...

  7. Android Touch事件分发过程

    虽然网络上已经有非常多关于这个话题的优秀文章了,但还是写了这篇文章,主要还是为了加强自己的记忆吧,自己过一遍总比看别人的分析要深刻得多.那就走起吧. 简单演示样例 先看一个演示样例 : 布局文件 : ...

  8. oracle 11gR2 如何修改scan vip 地址 /etc/hosts方式

    这次帮客户搭建了一套oracle 11gR2 rac for aix环境,scan vip因为网络调整需要,需要更改以前设置好的scan vip,是采用/etc/hosts的方式,比如将scan vi ...

  9. query.setFirstResult解析

    转自:https://blog.csdn.net/thinkingcao/article/details/78053622

  10. 剑指offer——06旋转数组的最小数字(Python3)

    题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数 ...