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

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

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

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

 #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. Vue学习之路第十五篇:v-if和v-show指令

    1.v-if和v-show都是用来实现条件判断的指令. 2.先看代码 <body> <div id="app"> <button @click=&qu ...

  2. NOIP2016 DAY2 T1 组合数问题

    题目描述 组合数表示的是从n个物品中选出m个物品的方案数.举个例子,从(1,2,3) 三个物品中选择两个物品可以有(1,2),(1,3),(2,3)这三种选择方法.根据组合数的定 义,我们可以给出计算 ...

  3. win10 1809磁盘占用总是100%

    快过年了,提前请假回家,装几台电脑公司备用.有个电脑装完系统开机很慢,开机完成之后电脑响应也很慢,于是打开任务管理器发现磁盘中用率一直是100%,然而程序读取数据的速度并不高. 解决思路: 关闭win ...

  4. Java工具类使用注意事项

    (以下摘自阿里巴巴Java开发手册) 1. [强制]获取单例对象需要保证线程安全,其中的方法也要保证线程安全. 说明:资源驱动类.工具类.单例工厂类都需要注意. 5. [强制]SimpleDateFo ...

  5. 最大团&稳定婚姻系列

    [HDU]   1530 Maximum Clique 1435 Stable Match 3585 maximum shortest distance 二分+最大团 1522 Marriage is ...

  6. Elasticsearch---基于scroll技术滚动搜索大量数据

    如果一次性要查出来比如10万条数据,那么性能会很差,此时一般会采取用scoll滚动查询,一批一批的查,直到所有数据都查询完处理完 使用scoll滚动搜索,可以先搜索一批数据,然后下次再搜索一批数据,以 ...

  7. MYSQL数据的安装、配置

    linux安装mysql服务分两种安装方法: 1.源码安装,优点是安装包比较小,只有十多M,缺点是安装依赖的库多,安装编译时间长,安装步骤复杂容易出错. 2.使用官方编译好的二进制文件安装,优点是安装 ...

  8. mysql开发之---每日一得01

    2015年7月7日------------------------- 1.truncate表会清空建表语句auto_increment的值:某个表的id即是主键也是自增,你能够选择插入随意id值,假设 ...

  9. uva 10061(数学)

    题解:题目要在b进制下输出的是一个数字阶乘后有多少个零,然后输出一共同拥有多少位.首先计算位数,log(n)/log(b) + 1就是n在b进制下有多少位,而log有个公式就是log(M×N) = l ...

  10. Quartz2D二维画图引擎

    Quartz2D二维画图引擎 这个二维画图引擎的功能很强大 一般苹果公司xcode 提供给我们的一些UI控件不能满足我们的需求 所以我们会自己定义控件 xcode 提供的全部控件都是由这个画图引擎画出 ...