题目链接

这道题求的是这些可能存在重叠的小方块可能构成的合成方块的周长的值是多少,有简单却会很复杂的做法就是去跑纵向和横向两次的扫描线,求得最后的两个周长和,但是这样的做法未免显得复杂了,我们完全可以只跑一次线段树(扫描线)来做到这样的要求。

思路:问题就是我们得去知道有多少个可以竖起来的边,也就是有在两条扫描线之间,有多少个独立的方块在其中?我们求得独立方块数,最后乘以2就是最后的竖的边的数量,那么在解决竖直边上的这个问题我们就首先解决了。接下去就是求解横向的边的长度,我们每次的扫描线,也就代表着目前处理到的线上有多长的区间,那么我们求一个与上一个状态的差值,就是目前没被覆盖的边的增加出来的周长了。于是,我们加起来就会得到最后的总的周长了。

 #include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxN = 1e4 + ;
int N, tot, X[maxN], _UP;
struct node
{
int lx, rx, y, val;
node(int a=, int b=, int c=, int d=):lx(a), rx(b), y(c), val(d) {}
}line[maxN];
bool cmp(node e1, node e2) { return e1.y < e2.y; }
struct tree
{
int sum, siz, num;
bool lc, rc;
tree(int a=, int b=, int f=, bool c=false, bool d=false):sum(a), siz(b), num(f), lc(c), rc(d) {}
void clear() { sum = siz = num = ; lc = rc = false; }
}t[maxN<<];
inline void buildTree(int rt, int l, int r)
{
t[rt].clear();
if(l == r) return;
int mid = HalF;
buildTree(Lson);
buildTree(Rson);
}
inline void pushup(int rt, int l, int r)
{
if(t[rt].siz)
{
t[rt].sum = X[r + ] - X[l];
t[rt].lc = t[rt].rc = true;
t[rt].num = ;
}
else if(l == r)
{
t[rt].sum = t[rt].num = ;
t[rt].lc = t[rt].rc = false;
}
else
{
t[rt].sum = t[lsn].sum + t[rsn].sum;
t[rt].lc = t[lsn].lc; t[rt].rc = t[rsn].rc;
t[rt].num = t[lsn].num + t[rsn].num - (t[lsn].rc && t[rsn].lc);
}
}
inline void update(int rt, int l, int r, int ql, int qr, int val)
{
if(ql <= l && qr >= r)
{
t[rt].siz += val;
pushup(myself);
return;
}
int mid = HalF;
if(qr <= mid) update(QL, val);
else if(ql > mid) update(QR, val);
else { update(QL, val); update(QR, val); }
pushup(myself);
}
inline void init()
{
tot = ;
}
int main()
{
while(scanf("%d", &N) != EOF)
{
init();
int lx, ly, rx, ry;
for(int i=; i<=N; i++)
{
scanf("%d%d%d%d", &lx, &ly, &rx, &ry);
line[++tot] = node(lx, rx, ly, );
X[tot] = lx;
line[++tot] = node(lx, rx, ry, -);
X[tot] = rx;
}
sort(X + , X + tot + );
sort(line + , line + tot + , cmp);
_UP = (int)(unique(X + , X + tot + ) - X - );
buildTree(, , _UP);
int ans = , las = ;
for(int i=, l, r; i<tot; i++)
{
l = (int)(lower_bound(X + , X + _UP + , line[i].lx) - X);
r = (int)(lower_bound(X + , X + _UP + , line[i].rx) - X - );
update(, , _UP, l, r, line[i].val);
ans += abs(las - t[].sum);
las = t[].sum;
ans += (line[i + ].y - line[i].y) * (t[].num << );
}
ans += line[tot].rx - line[tot].lx;
printf("%d\n", ans);
}
return ;
}
/*
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
ans = 228
*/

Picture【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(线段树扫描线求周长)

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

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

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

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

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

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

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

  6. ●线段树的三个题(poj 3225,hdu 1542,hdu 1828)

    ●poj 3225 Help with Intervals(线段树区间问题) ○赘述题目 给出以下集合操作: 然后有初始的一个空集S,和以下题目给出的操作指令,并输入指令: 要求进行指令操作后,按格式 ...

  7. HDU 1828 / POJ 1177 Picture (线段树扫描线,求矩阵并的周长,经典题)

    做这道题之前,建议先做POJ 1151  Atlantis,经典的扫描线求矩阵的面积并 参考连接: http://www.cnblogs.com/scau20110726/archive/2013/0 ...

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

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

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

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

  10. (中等) HDU 1828 Picture,扫描线。

    Problem Description A number of rectangular posters, photographs and other pictures of the same shap ...

随机推荐

  1. 初学css 行内元素与块级元素

    行内元素与块级元素直观上的区别 1.行内元素会在一条直线上排列,都是同一行的,水平方向排列块级元素各占据一行,垂直方向排列.块级元素从新行开始结束接着一个断行. 2.块级元素可以包含行内元素和块级元素 ...

  2. TP5.1+Vue前后端分离实践

    配置: 主域名 www.demo.xyz 二级子域名 api.demo.xyz 列表项目其中api.demo.xyz加入了版本控制,使用的是URL路由传入方式 在route.php路由文件中配置,如下 ...

  3. 【数据库运维】数据库(server)的时区设置及世界主要地区的时区

    [时区设置不当会有什么问题] 当进行海外项目运维的时候,常常会遇到时区设置的问题.假设时区设置不当 或者 同样项目的server之间的时区不一致,都会有导致项目的数据异常的风险. 假设数据表的字段使用 ...

  4. asp.net Swiper 轮播动画

    原文:https://blog.csdn.net/qq_39656138/article/details/90451289 官网:https://www.swiper.com.cn/api/index ...

  5. Lambda创建表达式目录树

    一,如下代码: using System; using System.Linq.Expressions; namespace Demo { class Program { static void Ma ...

  6. vs code 同步

    vs code 同步需要在github上配置好gist id, 将gist id添加至setting.json中, 然后再在localsetting中设置access token,  gist id ...

  7. Azkaban和Oozie的区别

    Azkaban和Oozie的区别: 当前,实际生产中最流行的两种Hadoop工作流引擎是Azkaban与Oozie.但活跃度最高的当是Azkaban了,下面对两者的异同之处作如下对比. 功能对比 Az ...

  8. 一、IIS性能检测与网站管理

    一.性能监视器 1.Windows Server自带的性能监视器.(开始 运行 perfmon ) 另一种方式打开 Performance Monitor 点击Windows+R,在Run中输入per ...

  9. [web 安全] php随机数安全问题

    and() 和 mt_rand() 产生随机数srand() 和 mt_srand() 播种随机数种子(seed)使用: <?php srand(123);//播种随机数种子 for($i=0; ...

  10. bootstrap模态框模板代码

    模态框模板 模板代码 <!-- 添加员工的模态框 start --> <div class="modal fade" id="empAddModal&q ...