题意:给你n个矩形,然后矩形有可能重叠,要你求周长

思路:首先碰到这种矩形在数轴上那么第一反应应该想到的是扫描线,

做周长我们有两种方法

第一种,我们可以分开两部分求,第一遍求x轴上的贡献,第二遍求y轴上的贡献

首先第一条边我们可以直接加出贡献,第二条边我们和第一条有覆盖部分,那么我们要怎么加呢,我们会发现要加的也就是  ( 加入这条边后的线段树上最大长度-没加之前的最大长度)

然后我们再加进来,会看到加入出边的时候因为是-1了,所以加入后的长度会比没加之前的值小,但是贡献依然是他们的差值,那么我们就只要求绝对值即可

y轴上是一样的道理

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<cstdlib>
#include<algorithm>
#define mem(a,b) memset(a,b,sizeof(a))
#define inf 0x3f3f3f3f
#define N 10005
#define ll long long
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
struct Seg
{
int l,r,h;
int f;
Seg() {}
Seg(int a,int b,int c,int d):l(a),r(b),h(c),f(d) {}
bool operator < (const Seg &cmp) const
{
return h<cmp.h;
}
} e[N],e2[N];
struct node
{
int cnt;
int len;
} t[N<<];
int X[N];
int Y[N];
void pushdown(int l,int r,int rt,int X[])
{
if(t[rt].cnt)//当前的边被标记,就把当前的长度加上
t[rt].len=X[r+]-X[l];
else if(l==r)//当为一个点的时候长度为0
t[rt].len=;
else//其他情况把左右两个区间的值加上
t[rt].len=t[rt<<].len+t[rt<<|].len;
}
void update(int L,int R,int l,int r,int rt,int val,int X[])
{
if(L<=l&&r<=R)
{
t[rt].cnt+=val;//加上标记的值
pushdown(l,r,rt,X);//像下更新节点
return;
}
int m=(l+r)>>;
if(L<=m) update(L,R,lson,val,X);
if(R>m) update(L,R,rson,val,X);
pushdown(l,r,rt,X);
}
int main()
{
int n;
int a,b,c,d;
while(scanf("%d",&n)!=EOF)
{
mem(t,);
int num=;
for(int i=; i<n; i++)
{
scanf("%d%d%d%d",&a,&b,&c,&d);
X[num]=a;Y[num]=b;
e[num]=Seg(a,c,b,);//矩形下面用1来标记吗
e2[num++]=Seg(b,d,a,);
X[num]=c;Y[num]=d;
e[num]=Seg(a,c,d,-);//上面用-1来标记
e2[num++]=Seg(b,d,c,-);
}
sort(Y,Y+num);
sort(X,X+num);//用于离散化
sort(e,e+num);//把矩形的边的纵坐标从小到大排序
sort(e2,e2+num);
int m=unique(X,X+num)-X;
int m2=unique(Y,Y+num)-Y;
int ans=;
int last=;
for(int i=; i<num; i++)
{
int l=lower_bound(X,X+m,e[i].l)-X;//找出离散化以后的值
int r=lower_bound(X,X+m,e[i].r)-X-;
update(l,r,,m,,e[i].f,X);
ans+=abs(last-t[].len);
last=t[].len;
}
last=;
memset(t,,sizeof(t));
for(int i=; i<num; i++)
{
int l=lower_bound(Y,Y+m2,e2[i].l)-Y;//找出离散化以后的值
int r=lower_bound(Y,Y+m2,e2[i].r)-Y-;
update(l,r,,m2,,e2[i].f,Y);
ans+=abs(last-t[].len);
last=t[].len;
}
printf("%d\n",ans);
}
return ;
}

第二种我暂时不会,先空着,只要求一遍扫描线

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

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

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

  2. HDU 1828“Picture”(线段树+扫描线求矩形周长并)

    传送门 •参考资料 [1]:算法总结:[线段树+扫描线]&矩形覆盖求面积/周长问题(HDU 1542/HDU 1828) •题意 给你 n 个矩形,求矩形并的周长: •题解1(两次扫描线) 周 ...

  3. hdu 4419 线段树 扫描线 离散化 矩形面积

    //离散化 + 扫描线 + 线段树 //这个线段树跟平常不太一样的地方在于记录了区间两个信息,len[i]表示颜色为i的被覆盖的长度为len[i], num[i]表示颜色i 『完全』覆盖了该区间几层. ...

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

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

  5. hdu 4052 线段树扫描线、奇特处理

    Adding New Machine Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  6. POJ-1151-Atlantis(线段树+扫描线+离散化)[矩形面积并]

    题意:求矩形面积并 分析:使用线段树+扫描线...因为坐标是浮点数的,因此还需要离散化! 把矩形分成两条边,上边和下边,对横轴建树,然后从下到上扫描上去,用col表示该区间有多少个下边,sum代表该区 ...

  7. hdu 5091(线段树+扫描线)

    上海邀请赛的一道题目,看比赛时很多队伍水过去了,当时还想了好久却没有发现这题有什么水题的性质,原来是道成题. 最近学习了下线段树扫描线才发现确实是挺水的一道题. hdu5091 #include &l ...

  8. HDU 5107 线段树扫描线

    给出N个点(x,y).每一个点有一个高度h 给出M次询问.问在(x,y)范围内第k小的高度是多少,没有输出-1 (k<=10) 线段树扫描线 首先离散化Y坐标,以Y坐标建立线段树 对全部的点和询 ...

  9. hdu1542 线段树扫描线求矩形面积的并

    题意:       给你n个正方形,求出他们的所占面积有多大,重叠的部分只能算一次. 思路:       自己的第一道线段树扫描线题目,至于扫描线,最近会写一个总结,现在就不直接在这里写了,说下我的方 ...

随机推荐

  1. [CF1161F]Zigzag Game

    通过这道模板题学了一种新的模型,记录一下. 稳定婚姻匹配 至于这道题,显然是一个二分图博弈的模型.考虑选择Bob,我们要找一组匹配使得任何情况下Bob都有匹配边能走.不失一般性假设Alice选择了in ...

  2. BDE(一款数据库引擎,通过它可以连接不同数据库)

    BDE(Borland Database Engine)是Inprise公司的数据库引擎,它结合了SQL Links允许程序员通过它能够连接到各种不同的数据库.BDE是BORLAND 数据库引擎的缩写 ...

  3. 5 August

    P1016 旅行家的预算 单调队列. 再看看单调队列怎么用的. #include <cstdio> int n, l, r; double D, dd, d[9], C, p[9], an ...

  4. [CSP-S模拟测试]:chinese(数学)

    题目传送门(内部题25) 输入格式 一行三个整数$n,m,k$. 输出格式 一行一个整数表示答案. 样例 样例输入: 2 2 2 样例输出: 数据范围与提示 样例解释: $f_0=10,f_1=4,f ...

  5. [CSP-S模拟测试]:树(树形DP+期望)

    题目描述 梦游中的你来到了一棵$N$个节点的树上.你一共做了$Q$个梦,每个梦需要你从点$u$走到点$v$之后才能苏醒,由于你正在梦游,所以每到一个节点后,你会在它连出去的边中等概率地选择一条走过去, ...

  6. 异常的处理try-catch

    Java异常处理 Java采用的异常处理机制,是将异常处理的程序代码集中在一起, 与正常的程序代码分开,使得程序简洁.优雅,并易于维护. * 异常的处理: 抓抛模型*** 过程一 : 抛, 程序在执行 ...

  7. 嵌入式C语言3.2 关键字---自定义数据类型

    1. struct 结构体 基本语法 struct myabc{ unsigned int a; unsigned int b; unsigned int c; unsigned int d; } 调 ...

  8. 哈希算法和字典类的定义,DataSet中数据遍历的几种方法

    哈希算法的基本操作: 1.  哈希表(HashTable)简述   在.NET Framework中,Hashtable是System.Collections命名空间提供的一个容器,用于处理和表现类似 ...

  9. VS2013编译程序出现error C4996: 'std::_Fill_n': Function call with parameters that may be unsafe

    最近按照BiliBil网站Visual C++网络项目实战视频教程,使用VS2013编写一个基于MFC的对话框程序HttpSourceViewer,采用了WinHttp库.Boost xpressiv ...

  10. Qt 程序在 Windows 下的发布

    本文讨论在 Windows 平台下编译成功的 Qt 程序,如何在未配置 Qt 开发环境的 Windows 平台下独立运行的方法. 经过验证发现,在 Ubuntu 平台下编译成功的程序可在未安装 Qt ...