hdu-1255-覆盖的面积 线段树

来源:互联网 发布:大数据的数据库设计 编辑:程序博客网 时间:2024/06/06 20:46

和 hdu 1542差不多

http://www.cnblogs.com/kuangbin/archive/2012/08/15/2640865.html


#include<stdio.h>#include<string.h>#include<stdlib.h>#include<iostream>#include<algorithm>#include<vector>#include<math.h>using namespace std;#define ll long long#define N 1010struct node{int l,r,cover;double dl,dr,len,len2;}tree[8*N];double yt[2*N];struct line{double y1,y2;double x;int flag;}p[2*N];void build(int id,int x,int y){tree[id].l=x;tree[id].r=y;tree[id].cover=0;tree[id].dl=yt[x];tree[id].dr=yt[y];tree[id].len=tree[id].len2=0;if(x+1==y) return ;int mid=(x+y)>>1;build(id<<1,x,mid);build((id<<1)+1,mid,y);}bool cmp(line a,line b){return a.x<b.x;}void update(int id){if(tree[id].cover>=2){tree[id].len2=tree[id].dr-tree[id].dl;tree[id].len=tree[id].dr-tree[id].dl;}else if(tree[id].cover==1){tree[id].len=tree[id].dr-tree[id].dl;if(tree[id].l+1==tree[id].r)tree[id].len2=0;elsetree[id].len2=tree[id<<1].len+tree[(id<<1)+1].len;}else if(tree[id].l+1==tree[id].r)tree[id].len=tree[id].len2=0;else{tree[id].len=tree[id<<1].len+tree[(id<<1)+1].len;tree[id].len2=tree[id<<1].len2+tree[(id<<1)+1].len2;}}void add(int id,line e){if(tree[id].dl==e.y1 && tree[id].dr==e.y2){tree[id].cover+=e.flag;update(id);return ;}if(tree[id<<1].dr>=e.y2)add(id<<1,e);else if(tree[(id<<1)+1].dl<=e.y1)add((id<<1)+1,e);else{line t=e;t.y2=tree[id<<1].dr;add(id<<1,t);t=e;t.y1=tree[(id<<1)+1].dl;add((id<<1)+1,t);}update(id);}int main(){int n,i,j,k;int t;scanf("%d",&t);while(t--){scanf("%d",&n);int cnt=0;for(i=0;i<n;i++){double x1,y1,x2,y2;scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);p[cnt].x=x1;p[cnt].y1=y1;p[cnt].y2=y2;p[cnt].flag=1;yt[cnt]=y1;cnt++;p[cnt].x=x2;p[cnt].y1=y1;p[cnt].y2=y2;p[cnt].flag=-1;yt[cnt]=y2;cnt++;}sort(p,p+cnt,cmp);sort(yt,yt+cnt);build(1,0,cnt-1);double sum=0;for(i=0;i<cnt-1;i++){add(1,p[i]);sum+=(p[i+1].x-p[i].x)*tree[1].len2;}printf("%.2lf\n",sum);}}



下面代码以前写的,太垃圾。。

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;#define N 2100double x1,Y1,x2,y2;struct node{double len,len2;int cover,l,r;}tree[6*N];double yy[2*N];struct pos{double x,y1,y2;int flag;}line[2*N];bool cmp(pos a,pos b){return a.x<b.x;}void build(int id,int x,int y){tree[id].l=x;tree[id].r=y;tree[id].len=tree[id].len2=0;tree[id].cover=0;if(x+1==y)return ;int mid=(x+y)>>1;build(id<<1,x,mid);build((id<<1)+1,mid,y);}int cnt;int find(double x){int l=0,r=cnt-1;while(l<=r){int mid=(l+r)>>1;if(yy[mid]==x) return mid;else if(yy[mid]>x) r=mid-1;else l=mid+1;}return l;}void add(int id,int x,int y,int h){if(tree[id].l+1==tree[id].r){tree[id].cover+=h;if(tree[id].cover>=2) tree[id].len=yy[tree[id].r]-yy[tree[id].l];else tree[id].len=0;return ;}int mid=(tree[id].l+tree[id].r)>>1;if(mid>=y) add(id<<1,x,y,h);else if(mid<=x) add((id<<1)+1,x,y,h);else{add(id<<1,x,mid,h);add((id<<1)+1,mid,y,h);}tree[id].len=tree[id<<1].len+tree[(id<<1)+1].len;}int main(){int n,i,j,k;int t;scanf("%d",&t);while(t--){cin>>n;cnt=0;for(i=0;i<n;i++){scanf("%lf%lf%lf%lf",&x1,&Y1,&x2,&y2);yy[cnt]=Y1;line[cnt].flag=1;line[cnt].x=x1;line[cnt].y1=Y1;line[cnt++].y2=y2;yy[cnt]=y2;line[cnt].flag=-1;line[cnt].x=x2;line[cnt].y1=Y1;line[cnt++].y2=y2;}sort(yy,yy+cnt);sort(line,line+cnt,cmp);build(1,0,cnt-1);double sum=0;for(i=0;i<cnt-1;i++){int a=find(line[i].y1);int b=find(line[i].y2);add(1,a,b,line[i].flag);sum+=(line[i+1].x-line[i].x)*tree[1].len;}printf("%.2lf\n",sum);}}


0 0