HDU 1828 Picture(长方形的周长和)
HDU 1828 Picture
题意:给定n个矩形,输出矩形周长并
思路:利用线段树去维护,分别从4个方向扫一次,每次多一段的时候,就查询该段未被覆盖的区间长度,然后周长就加上这个长度,4个方向都加完就是答案
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int N = 5005; int n; struct Rec {
int x1, y1, x2, y2;
void read() {
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
x1 += 10000; y1 += 10000; x2 += 10000; y2 += 10000;
}
} rec[N]; struct Line {
int l, r, y, flag;
Line() {}
Line(int l, int r, int y, int flag) {
this->l = l; this->r = r;
this->y = y; this->flag = flag;
}
} line[N * 2]; bool cmp1(Line a, Line b) {
if (a.y == b.y) return a.flag > b.flag;
return a.y < b.y;
} bool cmp2(Line a, Line b) {
if (a.y == b.y) return a.flag > b.flag;
return a.y > b.y;
} #define lson(x) ((x<<1)+1)
#define rson(x) ((x<<1)+2) struct Node {
int l, r, add, addv, num;
bool cover;
void init(int l, int r) {
this->l = l; this->r = r;
add = addv = num = 0;
cover = false;
}
void gao(int v) {
addv += v;
if (add == 0) num = r - l + 1;
add += v;
if (add == 0) num = 0;
}
} node[4 * 20005]; void pushup(int x) {
if (node[lson(x)].cover && node[rson(x)].cover && node[lson(x)].add == node[rson(x)].add) {
node[x].cover = true;
node[x].add = node[lson(x)].add;
} else node[x].cover = false;
node[x].num = node[lson(x)].num + node[rson(x)].num;
} void pushdown(int x) {
if (node[x].addv) {
node[lson(x)].gao(node[x].addv);
node[rson(x)].gao(node[x].addv);
node[x].addv = 0;
}
} void build(int l, int r, int x = 0) {
node[x].init(l, r);
if (l == r) {
node[x].cover = true;
return;
}
int mid = (l + r) / 2;
build(l, mid, lson(x));
build(mid + 1, r, rson(x));
pushup(x);
} void add(int l, int r, int v, int x = 0) {
if (node[x].cover && node[x].l >= l && node[x].r <= r) {
node[x].gao(v);
return;
}
int mid = (node[x].l + node[x].r) / 2;
pushdown(x);
if (l <= mid) add(l, r, v, lson(x));
if (r > mid) add(l, r, v, rson(x));
pushup(x);
} int query(int l, int r, int x = 0) {
if (node[x].cover && node[x].l >= l && node[x].r <= r)
return node[x].num;
int mid = (node[x].l + node[x].r) / 2;
pushdown(x);
int ans = 0;
if (l <= mid) ans += query(l, r, lson(x));
if (r > mid) ans += query(l, r, rson(x));
pushup(x);
return ans;
} int solve() {
build(0, 20000);
int ans = 0;
for (int i = 0; i < 2 * n; i++) {
if (line[i].flag)
ans += line[i].r - line[i].l - query(line[i].l, line[i].r - 1);
add(line[i].l, line[i].r - 1, line[i].flag);
}
return ans;
} int gao() {
int ans = 0;
for (int i = 0; i < n; i++) {
line[i * 2] = Line(rec[i].x1, rec[i].x2, rec[i].y1, 1);
line[i * 2 + 1] = Line(rec[i].x1, rec[i].x2, rec[i].y2, -1);
}
sort(line, line + 2 * n, cmp1);
ans += solve();
for (int i = 0; i < n; i++) {
line[i * 2] = Line(rec[i].x1, rec[i].x2, rec[i].y2, 1);
line[i * 2 + 1] = Line(rec[i].x1, rec[i].x2, rec[i].y1, -1);
}
sort(line, line + 2 * n, cmp2);
ans += solve();
return ans;
} int main() {
while (~scanf("%d", &n)) {
for (int i = 0; i < n; i++)
rec[i].read();
int ans = 0;
ans += gao();
for (int i = 0; i < n; i++) {
swap(rec[i].x1, rec[i].y1);
swap(rec[i].x2, rec[i].y2);
}
ans += gao();
printf("%d\n", ans);
}
return 0;
}
HDU 1828 Picture(长方形的周长和)的更多相关文章
- hdu 1828 Picture 切割线求周长
Picture Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Sub ...
- hdu 1828 线段树扫描线(周长)
Picture Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Sub ...
- HDU 1828 Picture(线段树扫描线求周长)
Picture Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Su ...
- HDU 1828“Picture”(线段树+扫描线求矩形周长并)
传送门 •参考资料 [1]:算法总结:[线段树+扫描线]&矩形覆盖求面积/周长问题(HDU 1542/HDU 1828) •题意 给你 n 个矩形,求矩形并的周长: •题解1(两次扫描线) 周 ...
- hdu 1828 Picture(线段树 || 普通hash标记)
http://acm.hdu.edu.cn/showproblem.php?pid=1828 Picture Time Limit: 6000/2000 MS (Java/Others) Mem ...
- HDU 1828 Picture (线段树+扫描线)(周长并)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1828 给你n个矩形,让你求出总的周长. 类似面积并,面积并是扫描一次,周长并是扫描了两次,x轴一次,y ...
- 51nod 1206 && hdu 1828 Picture (扫描线+离散化+线段树 矩阵周长并)
1206 Picture 题目来源: IOI 1998 基准时间限制:2 秒 空间限制:131072 KB 分值: 160 难度:6级算法题 收藏 关注 给出平面上的N个矩形(矩形的边平行于X轴 ...
- hdu 1828 Picture(线段树扫描线矩形周长并)
线段树扫描线矩形周长并 #include <iostream> #include <cstdio> #include <algorithm> #include &l ...
- HDU 1828 Picture (线段树:扫描线周长)
依然是扫描线,只不过是求所有矩形覆盖之后形成的图形的周长. 容易发现,扫描线中的某一条横边对答案的贡献. 其实就是 加上/去掉这条边之前的答案 和 加上/去掉这条边之后的答案 之差的绝对值 然后横着竖 ...
随机推荐
- IDFA的值什么时候会发生改变
在何种情况下 , 应用的IDFA值会发生改变? 近期工作中须要获得一个能够唯一地标示每个不同应用的ID,之前的苹果UDID已经不让使用了. 那么我们须要使用新的IDFA来引用.可是在某些情况下这个ID ...
- 复制文件时,如何显示进度条(使用BlockRead函数读取数据,并插入application.ProcessMessages)
procedure mycopyfile(sourcef,targetf:string;i:integer); var FromF,ToF:file; NumRead,NumWritten:Integ ...
- PAIP: Paradigms of Artificial Intelligence Programming
PAIP: Paradigms of Artificial Intelligence Programming PAIP: Paradigms of Artificial Intelligence Pr ...
- SQL视图索引
视图: 视图就相当于一个查询结果,它相对应的是表 表----真正存储数据的地方 视图---不存储数据,展示查询的结果 注意: 1.视图就是为了查询数据方便.一般不要试图向视图中插入数据,容易出错. 2 ...
- python glob 用通配符查找指定目录中的文件 - 开源中国社区
python glob 用通配符查找指定目录中的文件 - 开源中国社区 python glob 用通配符查找指定目录中的文件
- Java使用Socket传输文件遇到的问题(转)
1.写了一个socket传输文件的程序,发现传输过去文件有问题.找了一下午终于似乎找到了原因,记录下来警示一下: 接受文件的一端,向本地写文件之前使用Thread.sleep(time)休息一下就解决 ...
- python基础教程_学习笔记10:异常
异常 什么是异常 Python用异常对象来表示异常情况.遇到错误后,会引发异常.假设异常对象并未被处理或捕捉,程序就会用所谓的回溯(Traceback,一种错误信息)终止运行: >>> ...
- ADO.NET之1-数据库连接---ShinePans
ADO.NET技术主要包含Connection,Command,DataReader,DataAdapter,DateSet,DataTable等六种对象 1).Connection 对象的主要功能是 ...
- python语言学习5——输入和输出
输出 用print()在括号中加上字符串,就可以向屏幕上输出指定的文字. 注意点: 字符串用的是单引号 碰到逗号输出时就会输出一个空格 输入 python提供了一个input(),可以让用户输入一个字 ...
- 使用mysql-mmm实现MySQL高可用集群
背景:之前实现的mysql同步复制功能(见笔者之前文章http://blog.csdn.net/kingofworld/article/details/39210937)仅仅是双机热备功能,还不能做到 ...