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(长方形的周长和)的更多相关文章

  1. hdu 1828 Picture 切割线求周长

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

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

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

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

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

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

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

  5. hdu 1828 Picture(线段树 || 普通hash标记)

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

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

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

  7. 51nod 1206 && hdu 1828 Picture (扫描线+离散化+线段树 矩阵周长并)

    1206 Picture  题目来源: IOI 1998 基准时间限制:2 秒 空间限制:131072 KB 分值: 160 难度:6级算法题  收藏  关注 给出平面上的N个矩形(矩形的边平行于X轴 ...

  8. hdu 1828 Picture(线段树扫描线矩形周长并)

    线段树扫描线矩形周长并 #include <iostream> #include <cstdio> #include <algorithm> #include &l ...

  9. HDU 1828 Picture (线段树:扫描线周长)

    依然是扫描线,只不过是求所有矩形覆盖之后形成的图形的周长. 容易发现,扫描线中的某一条横边对答案的贡献. 其实就是 加上/去掉这条边之前的答案 和 加上/去掉这条边之后的答案 之差的绝对值 然后横着竖 ...

随机推荐

  1. OCA读书笔记(7) - 管理数据库存储结构

    7.Managing Database Storage Structures 逻辑结构 数据库的存储结构有物理结构和逻辑结构组成的 物理结构:物理上,oracle是由一些操作系统文件组成的 SQL&g ...

  2. 传智播客成都java培训中心秀就业

    传智播客成都java培训中心秀就业 2013年被称为"史上最难就业季",成都传智播客学员如何应对的呢? 成都传智播客的学员在工作经验上颇占优势,我们采用项目驱动式教学模式,具有多年开发实战经验及教学经 ...

  3. ovirt node的安装简介

    Ovirt安装模式  支持install,update,downupdate,reinstall四种安装方式.  install:全新安装(以前未安装过ovirt node).  update:安装比 ...

  4. 2014年百度之星程序设计大赛 - 资格赛 第二题 Disk Schedule

    双调欧几里得旅行商问题是一个经典动态规划问题.<算法导论(第二版)>思考题15-1和北京大学OJ2677都出现了这个题目. 旅行商问题描写叙述:平面上n个点,确定一条连接各点的最短闭合旅程 ...

  5. [置顶] github简单使用

    git的介绍可以看这里   http://zh.wikipedia.org/wiki/GitHub 安装和使用参考的这个    http://www.cnblogs.com/cocowool/arch ...

  6. ios 上拉载入下拉刷新Dome

    为练手写了一个小的上拉载入很多其它下拉刷新的小的Dome . 没有太多的技术含量,仅仅是作为新手的启示用.是上一篇下拉载入的扩展.先看一下那个再看这个就easy非常多. Dome下载:http://d ...

  7. Twitter僵尸帐号厂商雇佣中国员工专填验证码_Web2.0 - Microblogging 微博_cnBeta.COM

    Twitter僵尸帐号厂商雇佣中国员工专填验证码_Web2.0 - Microblogging 微博_cnBeta.COM Twitter僵尸帐号厂商雇佣中国员工专填验证码

  8. Conexant声卡实现内录功能(win7)

    Conexant声卡本身没有立体声混音设备可选,所以我们采用virtual audio device,实现内录功能. [1]下载virtual audio device.下载地址:http://dow ...

  9. Hdu 4734 【数位DP】.cpp

    题意: 我们定义十进制数x的权值为f(x) = a(n)*2^(n-1)+a(n-1)*2(n-2)+...a(2)*2+a(1)*1,a(i)表示十进制数x中第i位的数字. 题目给出a,b,求出0~ ...

  10. ArrayList线程不安全?

    ArrayList是线程不安全的,轻量级的.如何使ArrayList线程安全? 1.继承Arraylist,然后重写或按需求编写自己的方法,这些方法要写成synchronized,在这些synchro ...