HDU 1828:Picture(扫描线+线段树 矩形周长并)
题意
给出n个矩形,求周长并。
思路
学了区间并,比较容易想到周长并。
我是对x方向和y方向分别做两次扫描线。应该记录一个pre变量,记录上一次扫描的时候的长度,对于每次遇到扫描线统计答案的时候,使用当前的 tree[1] 去与 pre 做相减,因为这一次如果边长增加了或者减少了,那么一定和之前的值有差值,其中的差值就是这次的变化量。
但是这份代码交G++会WA,C++就A了。而且排序的时候如果权值相同,应该让状态为1(开始)的扫描线排在状态为-1(结束)的扫描线前面,因为重合的话,那个边长不可计算到答案里面的。如果先更新结束的,代表这一段边长(如果更新之后消失了的话)会导致算上这一部分的贡献,然后又更新开始的,又算上一次这一部分的贡献,等于算上了两次。然而真实情况下,是不应该算上这部分的贡献的。
这题不用离散化也可以,习惯性。
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 2e4 + 10;
#define lson l, m, rt<<1
#define rson m + 1, r, rt<<1|1
typedef long long LL;
struct Node {
int l, r, w, st;
Node () {}
Node (int _l, int _r, int _w, int _st) {
l = _l, r = _r, w = _w, st = _st;
}
bool operator < (const Node &rhs) const {
if(w == rhs.w) return st > rhs.st; // 开始在结束前面
return w < rhs.w;
}
} px[N], py[N];
int tree[N<<2], cnt[N<<2];
int x[N], y[N];
void pushup(int l, int r, int rt, int *axis) {
if(cnt[rt] > 0) tree[rt] = axis[r+1] - axis[l];
else if(l == r) tree[rt] = 0;
else tree[rt] = tree[rt<<1] + tree[rt<<1|1];
}
void update(int L, int R, int w, int l, int r, int rt, int *axis) {
if(L <= l && r <= R) {
cnt[rt] += w;
pushup(l, r, rt, axis);
return ;
}
int m = (l + r) >> 1;
if(L <= m) update(L, R, w, lson, axis);
if(m < R) update(L, R, w, rson, axis);
pushup(l, r, rt, axis);
}
int solve(int n, int *axis, Node *p, int ct) {
memset(tree, 0, sizeof(tree));
memset(cnt, 0, sizeof(cnt));
int ans = 0, pre = 0;
for(int i = 1; i <= n; i++) {
int L = lower_bound(axis + 1, axis + 1 + ct, p[i].l) - axis;
int R = lower_bound(axis + 1, axis + 1 + ct, p[i].r) - axis - 1;
update(L, R, p[i].st, 1, ct, 1, axis);
ans += abs(tree[1] - pre);
pre = tree[1];
}
return ans;
}
int main() {
int n;
while(~scanf("%d", &n)) {
int cntx = 0, cnty = 0;
for(int i = 1; i <= n; i++) {
int x1, x2, y1, y2;
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
x[++cntx] = x1; x[++cntx] = x2;
y[++cnty] = y1; y[++cnty] = y2;
px[i*2-1] = Node(y1, y2, x1, 1);
px[i*2] = Node(y1, y2, x2, -1);
py[i*2-1] = Node(x1, x2, y1, 1);
py[i*2] = Node(x1, x2, y2, -1);
}
sort(x + 1, x + 1 + cntx);
sort(y + 1, y + 1 + cnty);
cntx = unique(x + 1, x + 1 + cntx) - x - 1;
cnty = unique(y + 1, y + 1 + cnty) - y - 1;
int m = 2 * n;
sort(px + 1, px + 1 + m);
sort(py + 1, py + 1 + m);
int ans = solve(m, x, py, cntx) + solve(m, y, px, cnty);
printf("%d\n", ans);
}
return 0;
}
/*
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
*/
HDU 1828:Picture(扫描线+线段树 矩形周长并)的更多相关文章
- HDU 1828“Picture”(线段树+扫描线求矩形周长并)
传送门 •参考资料 [1]:算法总结:[线段树+扫描线]&矩形覆盖求面积/周长问题(HDU 1542/HDU 1828) •题意 给你 n 个矩形,求矩形并的周长: •题解1(两次扫描线) 周 ...
- hdu 1828 Picture(线段树扫描线矩形周长并)
线段树扫描线矩形周长并 #include <iostream> #include <cstdio> #include <algorithm> #include &l ...
- HDU 1828 Picture(线段树扫描线求周长)
Picture Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Su ...
- hdu 1828 Picture(线段树,扫描线)
A number of rectangular posters, photographs and other pictures of the same shape are pasted on a wa ...
- luogu P1856 [USACO5.5]矩形周长Picture 扫描线 + 线段树
Code: #include<bits/stdc++.h> #define maxn 200007 #define inf 100005 using namespace std; void ...
- HDU 1542:Atlantis(扫描线+线段树 矩形面积并)***
题目链接 题意 给出n个矩形,求面积并. 思路 使用扫描线,我这里离散化y轴,按照x坐标从左往右扫过去.离散化后的y轴可以用线段树维护整个y上面的线段总长度,当碰到扫描线的时候,就可以统计面积.这里要 ...
- hdu1828(线段树——矩形周长并)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1828 分析:与面积不同的地方是还要记录竖的边有几个(num记录),并且当边界重合的时候需要合并(用lb ...
- 51nod 1206 && hdu 1828 Picture (扫描线+离散化+线段树 矩阵周长并)
1206 Picture 题目来源: IOI 1998 基准时间限制:2 秒 空间限制:131072 KB 分值: 160 难度:6级算法题 收藏 关注 给出平面上的N个矩形(矩形的边平行于X轴 ...
- poj 1151 Atlantis (离散化 + 扫描线 + 线段树 矩形面积并)
题目链接题意:给定n个矩形,求面积并,分别给矩形左上角的坐标和右上角的坐标. 分析: 映射到y轴,并且记录下每个的y坐标,并对y坐标进行离散. 然后按照x从左向右扫描. #include <io ...
随机推荐
- 大数据_zookeeper环境搭建中的几个坑
文章目录 [] Zookeeper简介 关于zk的介绍, zk的paxos算法, 网上已经有各位大神在写了, 本文主要写我在搭建过程中的几个极有可能遇到的坑. Zookeeper部署中的坑 坑之一 E ...
- wpf C# 操作DirectUI窗口 SendMessage+MSAA
原文:wpf C# 操作DirectUI窗口 SendMessage+MSAA 最近做一个抓取qq用户资料的工具,需要获取qq窗口上的消息,以前这种任务是用句柄获取窗口中的信息,现在qq的窗口用的是D ...
- javascript高程笔记-------第四章 变量、作用域和内存问题
首先JavaScript中的变量分为基本类型和引用类型. 基本类型就是保存在栈内存中的简单数据段,而引用类型指的是那些保存在堆内存中的对象. 1.参数传递 javascript中所有参数的传递都是值传 ...
- glibc_error reporting
很多GNU C库里的函数都会侦测并报告错误条件.我们的程序需要检测这些错误条件.比如:我们打开一个输入文件时需要判断该文件是否正确的打开.如果没有正确打开,我们需要打印错误或者采取其他正确的方式.为了 ...
- 【转】关于List排序的时效性
不多说了,就是说明List排序的时效性,仅仅用来备忘,改造自: http://blog.csdn.net/wanzhuan2010/article/details/6205884,感谢原作者 usin ...
- css3 位置选择器 类似jq的:eq(0)
JQ使用 :eq(位置),可以选择第几个元素 CSS3里面新增了一个用法,:nth-child(位置) 可实现和JQ同样的功能 需要注意的是jq第一个是从0开始,CSS的第一个是从1开始
- window 10 64bit Tortoise SVN 图标状态显示不正常
https://www.cnblogs.com/lzpong/p/6187366.html 根据以上帖子处理 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows ...
- ArcGIS 10.3 for Server 在windows下的安装教程
原文:ArcGIS 10.3 for Server 在windows下的安装教程 以下是10.2的教程,10.3同样适用. 许可文件: ArcGIS For Server10.3许可文件 - 下载频道 ...
- WPF ListView 数据懒加载
实现方式:当滑动条触底时,加载数据 xaml代码: <ListView ScrollViewer.ScrollChanged="ListView_ScrollChanged" ...
- 简单图标转xaml代码
工具 PhotoShopCC(2017) Blend 2017 原图 步骤 1,使用钢笔工具勾勒出大致路径 2,将工作路径转为形状路径 3,图层右键->复制SVG <svg xmlns=& ...