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 (线段树:扫描线周长)
依然是扫描线,只不过是求所有矩形覆盖之后形成的图形的周长. 容易发现,扫描线中的某一条横边对答案的贡献. 其实就是 加上/去掉这条边之前的答案 和 加上/去掉这条边之后的答案 之差的绝对值 然后横着竖 ...
随机推荐
- 积累的VC编程小技巧之列表框
1.列表框中标题栏(Column)的添加 创建一个List Control,其ID为IDC_LIST,在其Styles属性项下的View项里选择Report.Align项里选择Top.Sort项里选择 ...
- camel-name-utils 在驼峰风格跟下划线风格之间切换
用处 用来将字符串在驼峰风格跟下划线风格之间切换. 对于一般人可能没用.对于写orm框架的人有点作用. 样例: company_name -> companyName 安装方式 加入下面依赖到p ...
- 开源中国IOSclient
我想看看别人开发项目.通过吸收经验,然后找到开放的中国,丹尼尔一些网上也开发了自己的开源在中国client 在网上看到很多网友说,不能下载东西像安装,我带来了我的方式,其中的一些朋友想帮忙. http ...
- 网络编程API-上 (基本API)
htons.ntohs.htonl和ntohl函数 Linux提供了4个函数来完毕主机字节序和网络字节序之间的转换 #include <netinet/in.h> uint16_t hto ...
- IP Editor IP控件(对比一下封装IP控件)
HWND hIpEdit; void __fastcall TForm2::FormCreate(TObject *Sender) { hIpEdit = CreateWindow(WC_IPADDR ...
- 不断摸索发现用 andy 模拟器很不错,感觉跟真机差不多
嗯,今天也遇到了模拟的问题.那个慢啊,好几分钟才能开机,加载程序总共差不多十几分钟.当时想如果真做android开发必须换电脑啊.后来不断摸索发现用 andy 模拟器很不错,感觉跟真机差不多. 还是真 ...
- Codeforces Round #296 (Div. 2) A B C D
A:模拟辗转相除法时记录答案 B:3种情况:能降低2,能降低1.不能降低分别考虑清楚 C:利用一个set和一个multiset,把行列分开考虑.利用set自带的排序和查询.每次把对应的块拿出来分成两块 ...
- cocos2d-x项目101次相遇: Scenes , Director, Layers, Sprites
cocos2d-x 101次相遇 / 文件夹 1 安装和环境搭建 -xcode 2 Scenes , Director, Layers, Sprites 3 建立图片菜单 4 在 ...
- [Python]网络爬虫(十):一个爬虫的诞生全过程(以山东大学绩点运算为例)
先来说一下我们学校的网站: http://jwxt.sdu.edu.cn:7777/zhxt_bks/zhxt_bks.html 查询成绩需要登录,然后显示各学科成绩,但是只显示成绩而没有绩点,也就是 ...
- mysql基础:登录退出,修改用户密码,添加删除用户
今天刚开始学习mysql,最先接触用户管理,给大家分享下 注:mysql中命令的大小写都可以的 ==========登录退出相关=================== root@jack-deskto ...