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. 转载【浅谈ThreadPool 线程池】

    浅谈ThreadPool 线程池 http://www.cnblogs.com/xugang/archive/2010/04/20/1716042.html

  2. 多个haproxy 之间跳转

    C:\>ping wechatTest.winfae.com 正在 Ping wechatTest.winfae.com [120.55.118.6] 具有 32 字节的数据: 来自 120.5 ...

  3. 低头看—SQL视频

    迷迷糊糊半个月过去了,耿大姐的数据库视频也在一知半解中看完.虽然耿大妈讲的很详细,很细心,但是我还是时不时的犯困(还不如看儿童英语动画片有精神呢)视频看是看完了,但东西不是自己的.这个时候就需要“颗粒 ...

  4. 小米手机usb共享网络mac

    今天.我想去FQgoogle,mac在墙上,不便于使用.甚至只是用Android手机wifi,打开墙软件.然后usb分享到mac.然后mac互联网. 在谈到一些复杂.其实,关键一,小米手机usb共享, ...

  5. HDU 3911 Black And White 分段树 题解

    Problem Description There are a bunch of stones on the beach; Stone color is white or black. Little ...

  6. Cocos2d-x 3.0 创建一个场景,并设置现场的时候,项目开始执行上主动

    头 #ifndef __TEST_H__ #define __TEST_H__ #include "cocos2d.h" USING_NS_CC; class Test : pub ...

  7. HDU 2444 The Accomodation of Students(推断是否是二分图)

    题目链接 题意:n个学生,m对关系,每一对互相认识的能住一个房间.问否把这些学生分成两组,要求每组的学生都互不认识.求最多须要多少个房间. 能否分成两组?也就是说推断是不是二分图,推断二分图的办法,用 ...

  8. [Cocos2d-x]节点的尺寸大小

    作为一个CCNode,本身没有大小而言,但是AddChild之后,便有了尺寸的概念. Cocos2d-x中对于一个节点的尺寸可以通过以下三个方法获取: CCSprite: getContentSize ...

  9. JavaEE session机制

    JavaEE session机制 Http协议: 在讲session之前,必须说下Http协议,HTTP是一个client和server端请求和应答的标准(TCP).由HTTPclient发起一个请求 ...

  10. 关于jdbc注冊驱动的那点事

    看到非常多人写jdbc连接工具类的时候,都会写到Class.forName()去显示载入类,一写错点点就会抛出ClassNotFoundException,关于显示载入类,究竟会不会产生作用呢? 參考 ...