HDU1542 POJ1151矩形面积合并(线段树+离散化)
来源:互联网 发布:恢复删除照片软件 编辑:程序博客网 时间:2024/05/21 10:53
本程序来自网上,仅作收藏之用,如有侵权请告之。
这里注意下扫描线段时r-1: int R=search(s[i].l,hash,m)-1;
计算底边长时r+1:if(mark[n])sum[n]=hash[right+1]-hash[left];
解释:假设现在有一个线段左端点是l=0,右端点是r=m-1
则我们去更新的时候,会算到sum[1]=hash[mid]-hash[left]+hash[right]-hash[mid+1]
这样的到的底边长sum是错误的,why?因为少算了mid~mid+1的距离,由于我们这利用了
离散化且区间表示线段,所以mid~mid+1之间是有长度的,比如hash[3]=1.2,hash[4]=5.6,mid=3
所以这里用r-1,r+1就很好理解了
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<queue>#include<algorithm>#include<map>#include<iomanip>#define INF 99999999using namespace std;const int MAX=200+10;int mark[MAX<<2];//记录某个区间的下底边个数double sum[MAX<<2];//记录某个区间的下底边总长度double hash1[MAX];//对x进行离散化,否则x为浮点数且很大无法进行线段树 //以横坐标作为线段(区间),对横坐标线段进行扫描//扫描的作用是每次更新下底边总长度和下底边个数,增加新面积 struct seg{//线段 double l,r,h; int d; seg(){} seg(double x1,double x2,double H,int c):l(x1),r(x2),h(H),d(c){} bool operator<(const seg &a)const{ return h<a.h; }}s[MAX];void Upfather(int n,int left,int right){ if(mark[n])sum[n]=hash1[right+1]-hash1[left];//表示该区间整个线段长度可以作为底边 else if(left == right)sum[n]=0;//叶子结点则底边长度为0(区间内线段长度为0) else sum[n]=sum[n<<1]+sum[n<<1|1];}void Update(int L,int R,int d,int n,int left,int right){ if(L<=left && right<=R){//该区间是当前扫描线段的一部分,则该区间下底边总长以及上下底边个数差更新 mark[n]+=d;//更新底边相差差个数 Upfather(n,left,right);//更新底边长 return; } int mid=left+right>>1; if(L<=mid)Update(L,R,d,n<<1,left,mid); if(R>mid)Update(L,R,d,n<<1|1,mid+1,right); Upfather(n,left,right);}int search(double key,double* x,int n){ int left=0,right=n-1; while(left<=right){ int mid=left+right>>1; if(x[mid] == key)return mid; if(x[mid]>key)right=mid-1; else left=mid+1; } return -1;}int main(){ int n,num=0; double x1,x2,y1,y2; freopen("a.txt","r",stdin); while(cin>>n,n){ int k=0; for(int i=0;i<n;++i){ cin>>x1>>y1>>x2>>y2; hash1[k]=x1; s[k++]=seg(x1,x2,y1,1); hash1[k]=x2; s[k++]=seg(x1,x2,y2,-1); } sort(hash1,hash1+k); sort(s,s+k); int m=1; for(int i=1;i<k;++i)//去重复端点 if(hash1[i] != hash1[i-1])hash1[m++]=hash1[i]; double ans=0; //memset(sum,0,sizeof sum);如果下面是i<k-1则要初始化,因为如果对第k-1条线段扫描时会使得mark,sum为0才不用初始化的 for(int i=0;i<k;++i){//扫描线段 int L=search(s[i].l,hash1,m); int R=search(s[i].r,hash1,m)-1; Update(L,R,s[i].d,1,0,m-1);//扫描线段时更新底边长度和底边相差个数 ans+=sum[1]*(s[i+1].h-s[i].h);//新增加面积 } printf("Test case #%d\nTotal explored area: %.2lf\n\n",++num,ans); } return 0;}
hello
阅读全文
0 0
- HDU1542 POJ1151矩形面积合并(线段树+离散化)
- poj1151 & hdu1542 Atlantis(扫描线+离散化+线段树)
- Poj1151/HDU1542(求并矩形覆盖的面积)分别用离散化处理,矩形切割,线段树三种方法实现.
- POJ1151 Atlantis(线段树,扫描线,离散化,矩形面积并)
- HDU1542——Atlantis(扫描线,线段树,矩形面积并,离散化)
- POJ1151-(线段树扫描线+离散化)求矩形面积并
- POJ1151 (HDU 1542) Atlantis【矩形面积并,线段树+离散化+扫描线模板】
- poj1151 Atlantis(线段树+扫描线+离散化,求矩形面积并)
- hdu1542/poj 1151 (线段树&离散化&求矩形面积并)
- hdu1542 Atlantis(扫描线+线段树+离散)矩形相交面积
- HDU1542 Atlantis(扫描线+矩形面积并+线段树)
- hdu1542 线段树 矩形面积并
- 【HDU1542】Atlantis【线段树】【矩形面积并】
- hdu1542 Atlantis【矩形面积并+线段树】
- 线段树、扫描线、离散化求面积并(hdu1542)
- poj1151(线段树+离散化)
- POJ1151 离散化求矩形面积的并
- poj1151平面矩形面积并,双离散化
- 文件操作实践(一)
- 【C#】var关键字
- Oracle | 给表和字段添加注释
- Spring事务学习笔记(二)
- HDU-1166 敌兵布阵
- HDU1542 POJ1151矩形面积合并(线段树+离散化)
- 剑指offer第11题(二进制中1的个数)
- rocketmq jmeter压测
- 一篇面经(BAT面试)
- [Python]网络数据采集概述(1)—页面访问及页面元素的解析
- iptables 优化
- NYOJ题目289/456/49-01背包问题汇总
- mysql 入门第二天 涉及连表查询
- LintCode二叉树的最大节点