hdu1255 覆盖的面积(线段树+离散化+扫描线)
来源:互联网 发布:天刀怎样下载捏脸数据 编辑:程序博客网 时间:2024/06/05 15:35
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1255
题目:可以参考hdu1542 http://blog.csdn.net/qq_36782366/article/details/75209119
思路:用sum数组记录重叠两次以上的边的长度 once数组记录重叠一次边的记录 方便于信息的向上传递
其他的与hdu1542一致,这里主要讲下这两个数组的使用
关于pushup函数的解释(重点)
void PushUp(int rt,int l,int r) {if (cnt[rt]>=2){sum[rt] = X[r+1] - X[l];//需要理解once[rt]=0;return;} if(cnt[rt]==1){sum[rt] = once[rt<<1]+once[rt<<1|1]+sum[rt<<1]+sum[rt<<1|1];once[rt]=X[r+1] - X[l]-sum[rt];return ;} if(cnt[rt]==0){sum[rt] = sum[rt<<1] + sum[rt<<1|1];once[rt]=once[rt<<1]+once[rt<<1|1];return ;}}
如果cntr【rt】等于2时,说明该区间被该区间长度的边覆盖了两层,所以对于sum(两层以上的的长度)就是该区间的长度,因为已经覆盖两层了,所以once长度即为0
如果cnt【rt】等于1时,说明该区间被该区间长度的边覆盖了一层,所以对于sum(两层以上的的长度)就是其子区间中覆盖一层和两层以上的长度和,对于once一层的长度为总的该区间长度减去两层以上的长度
如果cnt【rt】等于0时,说明该区间没有被该区间长度的边覆盖,所以对于sum(两层以上的的长度)就是其子区间中覆盖两层以上的长度和,对于once一层的长度即等于其子区间中覆盖一层的长度和
好了接下来直接上AC的代码
#include <cstdio>#include <cstring>#include <cctype>#include <algorithm>using namespace std;#define lson l , m , rt << 1#define rson m + 1 , r , rt << 1 | 1const int maxn = 22022;int cnt[maxn << 2];double sum[maxn << 2];double once[maxn<<2];double X[maxn];struct Seg{ double h , l , r; int s; Seg(){} Seg(double a,double b,double c,int d) : l(a) , r(b) , h(c) , s(d) {} bool operator < (const Seg &cmp) const { if( h==cmp.h)return s>cmp.s; return h < cmp.h; }}ss[maxn];void PushUp(int rt,int l,int r) { if (cnt[rt]>=2) { sum[rt] = X[r+1] - X[l];//需要理解 once[rt]=0; return; } if(cnt[rt]==1) { sum[rt] = once[rt<<1]+once[rt<<1|1]+sum[rt<<1]+sum[rt<<1|1]; once[rt]=X[r+1] - X[l]-sum[rt]; return ; } if(cnt[rt]==0) { sum[rt] = sum[rt<<1] + sum[rt<<1|1]; once[rt]=once[rt<<1]+once[rt<<1|1]; return ; }}void update(int L,int R,int c,int l,int r,int rt){ if (L <= l && r <= R) { cnt[rt] += c;//这个位置的边的条数 如果大于0时需要计入底边 PushUp(rt , l , r); return ; } int m = (l + r) >> 1; if (L <= m) update(L , R , c , lson); if (m < R) update(L , R , c , rson); PushUp(rt , l , r);}int main(){ int n , cas; scanf("%d",&cas); while (cas--) { scanf("%d",&n) ; int m = 0; while (n --) { double a , b , c , d; scanf("%lf%lf%lf%lf",&a,&b,&c,&d); X[m] = a; ss[m++] = Seg(a , c , b , 1); X[m] = c; ss[m++] = Seg(a , c , d , -1); } sort(X , X + m); sort(ss , ss + m); int k=unique(X,X+m)-X; memset(cnt , 0 , sizeof(cnt)); memset(sum , 0 , sizeof(sum)); memset(once, 0 , sizeof(once)); double ret = 0; for (int i = 0 ; i < m - 1 ; i ++) { int l=lower_bound(X,X+k,ss[i].l)-X; int r =lower_bound(X,X+k,ss[i].r)-X-1; if (l <= r) update(l , r , ss[i].s , 0 , k - 1, 1);//扫描线段时更新底边长度和底边相差个数 ret += sum[1] * (ss[i+1].h - ss[i].h);//底乘以高 } printf("%.2lf\n", ret); } return 0;}
阅读全文
0 0
- hdu1255 覆盖的面积 扫描线+线段树+离散化
- hdu1255--覆盖的面积(线段树+离散化+扫描线)
- HDU1255覆盖的面积(线段树+离散化+扫描线)
- hdu1255 覆盖的面积(线段树+离散化+扫描线)
- HDU1255 覆盖的面积(线段树,离散化,扫描线,矩形面积交)
- hdu1255 覆盖的面积(线段树+扫描线+离散化,求矩形面积并)
- 覆盖的面积 hdu1255 扫描线+线段树
- 覆盖的面积 hdu1255 扫描线+线段树
- 覆盖的面积(线段树+扫描线+离散化)
- HDU1255 覆盖的面积 (扫描线)
- 线段树扫描线(覆盖两次以上的面积和)hdu1255
- hdu1255 线段树+扫描线+离散化
- HDU1255-覆盖的面积(线段树+扫描线——面积交)
- 【hdu1255】覆盖的面积(矩形面积交+线段树+扫描线)
- hdu1255 覆盖的面积(矩形面积交+扫描线)
- HDU1255 覆盖的面积 (线段树求面积交)
- HDU1255 覆盖的面积 扫描线
- HDU1255 覆盖的面积 【扫描线】
- 新手学习vue必看
- web中TextBox的onblur onload 属性
- andriod返回时刷新上一级activity实现
- traceroute和tracert区别
- 智能聊天机器人小黄鸡及其制作方法
- hdu1255 覆盖的面积(线段树+离散化+扫描线)
- SQL:oracle 层次查询 start with connect by
- 算法系列——House Robber
- redis的相关操作和命令
- poj 3468 区间修改查询 解题报告
- 去除数组中重复的对象
- 欢迎使用CSDN-markdown编辑器
- git命令总结
- 关于Kinectv2的一些资料