题意:。。求周长并。。。

解析:参考求面积并

图借鉴自:https://www.cnblogs.com/shuaiwhu/archive/2012/04/22/2464876.html

 自下而上扫描 首先 加GH 接着 加 Node[1].numseg * 2 *(Edge[i+1].y - Edge[i].y)即两条竖边   然后 加 BD 但这时要减去GH  因为 LN = GH 重复加了一次

依次推理

与面积并不同的是 最上面的边不要忘了加上。。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <cmath>
#define mem(a, b) memset(a, b, sizeof(a))
using namespace std;
const int maxn = , INF = 0x7fffffff;
int X[maxn]; struct node{
int l, r, w; // l 和 r 分别为线段树的左右端点 w记录边重叠的情况
int numseg; // 记录竖边的对数
int lx, rx, sum; // sum代表当前区间线段的长度,lx和rx为线段的真实端点
bool lcover, rcover; // 标记当前区间的左右端点 与 numseg有关
}Node[maxn*]; struct edge{ // 存边
int lxx, rxx, y;
int f;
}Edge[maxn]; int cmp(edge a, edge b)
{
return a.y < b.y;
} void build(int k, int ll, int rr)
{
Node[k].l = ll, Node[k].r = rr;
Node[k].lx = X[ll];
Node[k].rx = X[rr];
Node[k].w = Node[k].numseg = , Node[k].sum = ;
Node[k].lcover = Node[k].rcover = false;
if(ll + == rr) return;
int m = (ll + rr) / ;
build(k*, ll, m);
build(k*+, m, rr);
} void down(int k)
{
if(Node[k].w > )
{
Node[k].sum = Node[k].rx - Node[k].lx;
Node[k].numseg = ;
Node[k].lcover = Node[k].rcover = true;
return;
}
if(Node[k].l + == Node[k].r)
{
Node[k].sum = ;
Node[k].numseg = ;
Node[k].lcover = Node[k].rcover = false;
}
else
{
Node[k].sum = Node[k*].sum + Node[k*+].sum;
Node[k].lcover = Node[k*].lcover, Node[k].rcover = Node[k*+].rcover;
Node[k].numseg = Node[k*].numseg + Node[k*+].numseg;
if(Node[k*].rcover && Node[k*+].lcover) Node[k].numseg--; //注意这里是左区间的右端点 和 右区间的左端点
}
} void update(int k, edge e)
{
if(Node[k].lx == e.lxx && Node[k].rx == e.rxx)
{
Node[k].w += e.f;
down(k);
return;
}
if(e.rxx <= Node[k*].rx) update(k*, e);
else if(e.lxx >= Node[k*+].lx) update(k*+, e);
else
{
edge temp = e;
temp.rxx = Node[k*].rx;
update(k*, temp);
temp = e;
temp.lxx = Node[k*+].lx;
update(k*+, temp);
}
down(k);
} int main()
{
int n, cnt = ;
scanf("%d",&n);
for(int i=; i<n; i++)
{
int x1, x2, y1, y2;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
Edge[++cnt].lxx = x1, Edge[cnt].rxx = x2, Edge[cnt].y = y1, Edge[cnt].f = ;
X[cnt] = x1;
Edge[++cnt].lxx = x1, Edge[cnt].rxx = x2, Edge[cnt].y = y2, Edge[cnt].f = -;
X[cnt] = x2;
}
sort(Edge+, Edge+cnt+, cmp);
sort(X+, X+cnt+);
int m = unique(X+, X+cnt+) - (X+);
build(, , m);
int ret = , last = ;
for(int i=; i<cnt; i++)
{
update(, Edge[i]);
ret += abs(Node[].sum - last); // 横边
ret += Node[].numseg * * (Edge[i+].y - Edge[i].y); // 加竖边
last = Node[].sum;
}
update(, Edge[cnt]);
ret += abs(Node[].sum - last); printf("%d\n",ret); return ;
}

POJ1177(扫描线求周长并)的更多相关文章

  1. N - Picture - poj 1177(扫描线求周长)

    题意:求周长的,把矩形先进行融合后的周长,包括内周长 分析:刚看的时候感觉会跟棘手,让人无从下手,不过学过扫描线之后相信就很简单了吧(扫描线的模板- -),还是不说了,下面是一精确图,可以拿来调试数据 ...

  2. HDU 1828 Picture(线段树扫描线求周长)

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

  3. poj 1177 --- Picture(线段树+扫描线 求矩形并的周长)

    题目链接 Description A number of rectangular posters, photographs and other pictures of the same shape a ...

  4. 扫描线矩形周长的并 POJ1177

    //扫描线矩形周长的并 POJ1177 // 我是按x轴 #include <iostream> #include <cstdio> #include <cstdlib& ...

  5. HDU-1828 Picture(扫描线 求矩形并的周长)

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

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

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

  7. 编写一个Shape类,具有属性:周长和面积; 定义其子类三角形和矩形,分别具有求周长的方法。 定义主类E,在其main方法中创建三角形和矩形类的对象, 并赋给Shape类的对象a、b,使用对象a、b来测试其特性。

    package shape; public class Shape { //定义成员变量 private double zhouchang; private double mianji; public ...

  8. C# 定积分求周长&面积原理 代码实现

    前言: 前些日子,因为工作原因,接触到了求解曲线周长,真的是搞了很久,学生时代真的很简单,但是如今的我来说,忘记了....很多人跟我应该一样. 所以来巩固加强一下记忆.一开始的时候,求周长嘛,找公式呗 ...

  9. TZOJ 2569 Wooden Fence(凸包求周长)

    描述 Did you ever wonder what happens to your money when you deposit them to a bank account? All banks ...

随机推荐

  1. [07] 使用注解完成IOC配置

    1.扫描配置 之前使用的Spring的Bean管理都是通过xml的配置文件来操作的,在Spring3.0之后已经引入了注解形式,Spring可以在指定路径下进行扫描,寻找标注了@Component.@ ...

  2. [08] AOP基本概念和使用

    1.什么是AOP AOP = Aspect Oriental Programing,即面向切面编程.什么概念,我们看如下的图片: 三个方法中,重复使用了代码A和代码B,典型的场景比如"开启事 ...

  3. 浅谈传感器常用Delta-SigmaADC

    过采样ADC,或噪声整形ADC,也叫Delta-Sigma ADC.名字很多,基本上都由求差电路,积分求和电路组成调制器,后续由数字滤波器获得Nbit数字输出.不管怎样,数学上的除法能够让你理解这类A ...

  4. C#集合Collections购物车Shopping Cart

    这篇是对象与集合操练,物件的创建,集合的一些基本功能,如添加,编辑,删除等功能. 对象,即是网店的商品物件,Insus.NET只为其添加2个属性,物件的ID的Key和名称ItemName以及2个构造函 ...

  5. Intel Artificial Intelligence Conference(2018.11.14)

    时间:2018.11.14地点:北京国贸大酒店

  6. Idea Live Template代码片段总结

    目录 Idea Live Template总结 一.演示 二.详细介绍 2.1 类型 2.2设置(win默认快捷键win+alt+s) 2.3 快捷键 2.4 实战 Idea Live Templat ...

  7. 使用阿里云cli管理安全组

    相比于python SDK方式,阿里云基于GO SDK开发了一整套CLI工具,可以通过调用RPC API来管理云资源,对编程能力不够的人来说是个福音. 而且,阿里云CLI的文档比SDK的文档更加全面, ...

  8. Centos7下ELK+Redis日志分析平台的集群环境部署记录

    之前的文档介绍了ELK架构的基础知识,日志集中分析系统的实施方案:- ELK+Redis- ELK+Filebeat - ELK+Filebeat+Redis- ELK+Filebeat+Kafka+ ...

  9. Linux下"负载均衡+高可用"集群的考虑点 以及 高可用方案说明(Keepalive/Heartbeat)

    当下Linux运维技术越来越受到企业的关注和追捧, 在某些企业, 尤其是牵涉到电子商务和电子广告类的网站,通常会要求作负载均衡和高可用的Linux集群方案.那么如何实施Llinux集群架构,才能既有效 ...

  10. 百度之星-1002-list应用

    用stl的list即可,注意...代码的简洁性(被debug伤痛)注意合并时可以手动pop,或者用splice进行合并,不能用merge!!!merge合并是自带排序!!! #include<b ...