hdu 1542 矩形交(线段树)
来源:互联网 发布:网易电台录制软件 编辑:程序博客网 时间:2024/06/05 19:09
所谓的离散化,大家可以简单的理解为,将一组很大的数据,浓缩为一组很小的数据,用这组数据来代替原数据的作用,
比如给你1000个数,数的范围为(1,1e18)我们这里就可以用离散化,由于只有1000个数,我们可以用一个数组的下标代表提供的每一数,如果需要这个数据了,由于是下标,可以直接通过下标获得,如此就是离散化。
扫描线的知识提供一个大牛的博客:http://www.cnblogs.com/scau20110726/archive/2013/04/12/3016765.html
讲得很基础,是个很不错的博客
然后提醒一下这个扫描线要注意的问题就是区间的问题
一般的线段树以及我们的区间修改合并,都有一个共同点,就是不会出现区间缺失的现象,什么叫区间缺失,顾名思义,区间缺失就是缺少一些区间没有进行运算,这里的扫描线就会遇到这个问题。
普遍的,我们的线段树以及数据区间分布是这样的:
[1, a][a + 1, b][b + 1, c][c + 1, d][d + 1, e]…….
但是如果只是简简单单的用这个来解决扫描线的问题会导致错误,为什么因为,他没有涉及到[a,a + 1],在扫描线中会出现[a,a + 1]中的数据,而常用的线段树的区间概念是无法解决这样的问题的,出现了所谓的区间缺失,怎样解决,下面的代码给出了解决方案,这里简单的提一下,就是利用[ , ),这个区间性质,左闭右开,即可解决区间缺失问题
#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <queue>using namespace std;typedef long long LL;#define lson rt << 1, l, mid#define rson rt << 1|1, mid + 1, rconst int MAXN = 2000 + 5;int Col[MAXN << 2], n, cnt, res;double X[MAXN << 2], Sum[MAXN << 2];struct seg { double l,r,h; int s; seg() {} seg(double l,double r,double h,int s):l(l),r(r),h(h),s(s) {} bool operator < (const seg & object) const { return h < object.h; }} S[MAXN];void pushup(int rt,int l,int r) { if (Col[rt]) Sum[rt] = X[r+1] - X[l];//利用[ , ),这个区间性质,左闭右开 else if (l == r) Sum[rt] = 0; else Sum[rt] = Sum[rt<<1] + Sum[rt<<1|1];}void update(int L, int R, int c,int rt,int l, int r) { if(L <= l && r <= R) { Col[rt] += c; pushup(rt,l,r); return ; } int mid = (l + r) >> 1; if(L <= mid) update(L, R, c, lson); if(R > mid) update(L, R, c, rson); pushup(rt,l,r);}int binary_find(double x){ int lb = -1,ub = res - 1; while(ub - lb > 1){ int mid = (lb + ub) >> 1; if(X[mid] >= x) ub = mid; else lb = mid; } return ub;}int main() { int cas = 1; while(~ scanf("%d", &n), n) { cnt = res = 0; for(int i = 0 ; i < n; i ++) { double a,b,c,d; scanf("%lf%lf%lf%lf",&a, &b, &c,&d); S[cnt] = seg(a, c, b, 1); X[cnt ++] = a; S[cnt] = seg(a, c, d, -1); X[cnt ++] = c; } sort(X, X + cnt); sort(S, S + cnt); res ++; for(int i = 1; i < cnt; i ++) { if(X[i] != X[i - 1]) X[res ++] = X[i]; } memset(Sum, 0, sizeof(Sum)); memset(Col, 0, sizeof(Col)); double ans = 0; for(int i = 0;i < cnt - 1;i ++){ int l = binary_find(S[i].l); int r = binary_find(S[i].r) - 1;//利用[ , ),这个区间性质,左闭右开 update(l, r, S[i].s, 1, 0, res - 1); ans += Sum[1] * (S[i + 1].h - S[i].h); } printf("Test case #%d\nTotal explored area: %.2lf\n\n",cas++ , ans); } return 0;}
阅读全文
0 0
- hdu 1542 矩形交(线段树)
- hdu 1542 矩形面积并 &&hdu 1255 矩形面积交 && hdu 1828 矩阵周长并 线段树+扫描线入门
- hdu 1255 线段树 求矩形面积的交
- 矩形面积交-线段树
- HDU 1255 覆盖的面积(线段树求矩形面积交)
- HDU 1255(线段树,扫描线,矩形的面积交)
- 矩形面积并、矩形面积交、矩形周长并(线段树、扫描线总结)
- 矩形面积并、矩形面积交、矩形周长并(线段树、扫描线总结)
- HDU-5700-区间交(线段树)
- hdu 5700 区间交(线段树)
- 线段树(求矩形并,交,并减交的面积)
- hdu 1255 线段树+离散化+扫描线 (矩形面积交
- HDU 1542 Atlantis(线段树求矩形面积并)
- hdu 1542 矩形面积并(扫描线+线段树)
- HDU 1542 Atlantis(线段树求矩形面积并)
- hdu 1542 (线段树求矩形面积并)
- HDU 1542 Atlantis(线段树矩形覆盖)
- HDU 2056 Rectangles(矩形面积交)
- 九度OJ题目1001:A+B for Matrices
- Win10 环境下安装配置 zsh
- Cento系统下docker的安装与卸载
- 设计模式学习---第三节:代理模式
- L2TP/IPSec一键安装脚本
- hdu 1542 矩形交(线段树)
- CentOS7服务器安装mysql
- Mac shell使用技巧总结
- 3个跨域请求 解释异步执行
- 线段树之扫描线之周长并
- JNI源码分析 (并实现JNI动态注册)
- Python知识点
- LightSwitch中自动编号的生成
- 算法——Permutation