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

*****************************************************************************************************************
#include<stdio.h>
#include<math.h>
#include<algorithm>
using namespace std; #define Lson r<<1
#define Rson r<<1|1 const int MAXN = 2e5+;
const int oo = 1e9+; struct stgmentTree
{///len 保存区间包含的边的长度,cover 保存区间被覆盖的次数, sum保存有多少个不相连的区间段
int L, R, len, cover, sum;
bool lb, rb;///左边和右边是否被覆盖
int mid(){return (R+L)>>;}
}a[MAXN<<];
///dir 等于 1 的时候代表左边,-1时候代表右边,右边会抵消左边
struct Point{int x, y1, y2, dir;}ege[MAXN];
int Hash[MAXN], nh;///保存离散化后的数据,nh表示元素个数 bool cmp(Point n1, Point n2)
{///把边按照x的值从左往右排序
return n1.x < n2.x;
}
///查找一条边的长度, x1 < x2
int findSegLen(int x1, int x2)
{///用下标可以直接检索值
return Hash[x2] - Hash[x1];
}
void buildTree(int r, int L, int R)
{
a[r].L = L, a[r].R = R, a[r].cover=; if(L == R-)return ; buildTree(Lson, L, a[r].mid());
buildTree(Rson, a[r].mid(), R);
}
void pushUp(int r)///合并操作
{///需要先注意本区间是否被覆盖
if(a[r].cover != )
{
a[r].len= findSegLen( a[r].L, a[r].R );
a[r].sum = a[r].lb = a[r].rb = ;
}
else if(a[r].L == a[r].R - )
{
a[r].len = ;
a[r].sum = a[r].lb = a[r].rb = ;
}
else
{///如果本区间未被覆盖,并且不为叶子节点,那么就等于子区间的和
a[r].len = a[Lson].len + a[Rson].len; a[r].lb = a[Lson].lb, a[r].rb = a[Rson].rb;
a[r].sum = a[Lson].sum + a[Rson].sum - (a[Lson].rb & a[Rson].lb);
} }
void upData(int r, int L, int R, int dir)
{
if( a[r].L == L && a[r].R == R )
{
a[r].cover += dir;
pushUp(r); return ;
} if(R <= a[r].mid())
upData(Lson, L, R, dir);
else if(L >= a[r].mid())
upData(Rson, L, R, dir);
else
{
upData(Lson, L, a[r].mid(), dir);
upData(Rson, a[r].mid(), R, dir);
} pushUp(r);
} int main()
{
int N; while(scanf("%d", &N) != EOF)
{
int i, x1, x2, y1, y2, k=, C=, pre=; nh = ; for(i=; i<N; i++)
{
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
ege[k].x=x1, ege[k].y1=y1, ege[k].y2=y2, ege[k++].dir=;///左边y
ege[k].x=x2, ege[k].y1=y1, ege[k].y2=y2, ege[k++].dir=-;///右边y
Hash[nh++] = y1, Hash[nh++] = y2;
} sort(Hash, Hash+nh);///排序去重复
nh = unique(Hash, Hash+nh) - Hash;
///离散化后的数据是从0下标开始的
buildTree(, , nh-); ///对边按照x排序
sort(ege, ege+k, cmp); for(i=; i<k-; i++)
{
int L = lower_bound(Hash, Hash+nh, ege[i].y1) - Hash;
int R = lower_bound(Hash, Hash+nh, ege[i].y2) - Hash; upData(, L, R, ege[i].dir); C += fabs(a[].len - pre) + (ege[i+].x - ege[i].x)*a[].sum * ;
pre = a[].len;
} printf("%d\n", C+pre);
} return ; }
N - Picture - poj 1177(扫描线求周长)的更多相关文章
- Picture POJ - 1177 (扫描线)
扫描线求周长,可以看成两条线,一条扫x轴,一条扫y轴,然后这两天线扫过去的 周长加起来,就是周长了 #include<map> #include<set> #include&l ...
- poj 1177 --- Picture(线段树+扫描线 求矩形并的周长)
题目链接 Description A number of rectangular posters, photographs and other pictures of the same shape a ...
- hdu1828 Picture(线段树+扫描线+矩形周长)
看这篇博客前可以看一下扫描线求面积:线段树扫描线(一.Atlantis HDU - 1542(覆盖面积) 二.覆盖的面积 HDU - 1255(重叠两次的面积)) 解法一·:两次扫描线 如图我们可以 ...
- POJ1177(扫描线求周长并)
题意:..求周长并... 解析:参考求面积并 图借鉴自:https://www.cnblogs.com/shuaiwhu/archive/2012/04/22/2464876.html 自下而上扫描 ...
- 求矩形的周长(线段树+扫描线) Picture POJ - 1177
题目链接:https://cn.vjudge.net/problem/POJ-1177 题目大意:求矩形外部的周长 具体思路:借用一下bin巨的一张图片. 我们按照y周从下往上的扫描线进行扫描,第一下 ...
- Picture POJ - 1177 线段树+离散化+扫描线 求交叉图像周长
参考 https://www.cnblogs.com/null00/archive/2012/04/22/2464876.html #include <stdio.h> #include ...
- Picture POJ - 1177(扫描线求面积并)
题意:求矩形并的面积.. 解析: 扫描线第一道题....自下而上扫描的... 如果不懂什么是扫描线戳我 #include <iostream> #include <cstdio> ...
- HDU 1828 Picture(线段树扫描线求周长)
Picture Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Su ...
- Picture POJ - 1177 (线段树-扫描线)
A number of rectangular posters, photographs and other pictures of the same shape are pasted on a wa ...
随机推荐
- MFC中全局变量的定义及使用
用MFC制作的工程由很多文件构成,它不能象一般C++程序那样随意在类外定义全局变量,在这里要想定义能被工程内多个文件共享的全局变量和函数必须用一些特殊方法才行.实际上有多种方法可以实现,这里只介绍两种 ...
- 配置Ssh免密码登录
配置Ssh免密码登录 一个master节点,两个client节点(client1.client2) 1.所有节点创建hadoop用户,并设置密码 以root账号登录: useradd hadoop p ...
- NYOJ 10 skiing动态规划心得
这道题目,拿到手中,首先想到的是搜索,但是,后来想了想搜索不知道从哪搜起,就看了一下分类,一看属于动态规划类的,因为以前没有接触过动态规划,所以在网上搜了一下动态规划的思想,看过之后也有想到将它们到周 ...
- AFNetworking3.0出现Error Domain=com.alamofire.error.serialization.response Code=-1016 "Request failed: unacceptable
在发送请求后一直报错, 浏览器解析却没有问题, 所以基本可以确定是AFNetworking的问题 下面是解决方法: AFHTTPSessionManager *manager = [AFHTTPSes ...
- libusb简介
概述 libusb是一个C库,它提供了通用的访问USB设备. 它的目的是供开发人员使用方便的生产与USB通信硬件的应用程序. 可移植的: 使用一个跨平台API,它提供了访问USB设备在Linux上,O ...
- linux初识-02常用命令
文件目录操作命令 ls 现实文件和目录列表 ls -l 列出文件的详细信息 ls -a 列出当前目录所有文件 包括隐藏的文件 mkdir 创建目录 -p 父目录不存在的情况下先生成父目录 cd 切换目 ...
- idea intellij 快捷键(ubuntu版本)
S + C + T 创建测试类 A + F12 开启终端 C + F12 查看类中的方法属性 ----随时更新,记录快捷方式
- jquery mobile 复选框和单选框
checkbox 和radio <!DOCTYPE html> <html> <head> <meta charset="utf-8"&g ...
- 使用HTML+CSS,jQuery编写的简易计算器后续(添加了键盘监听)
之前发布了一款简易的计算器,今天做了一下修改,添加了键盘监听事件,不用再用鼠标点点点啦 JS代码: var yunSuan = 0;// 运算符号,0-无运算;1-加法;2-减法;3-乘法;4-除法 ...
- showModalDialog-父窗体子窗体
showModalDialog使用例子,父窗口向子窗口传递值,子窗口设置父窗口的值,子窗口关闭的时候返回值到父窗口. farther.html --------------------------- ...