HUD 1255 面积覆盖 线扫描
2015-07-29 09:18
337 查看
求面积交
#include <iostream> #include <stdio.h> #include <math.h> #include <algorithm> #include <queue> #include <stack> #include <vector> #include <string> #include <string.h> #include <map> #include <set> using namespace std; #define maxn 11005 struct line { double x1,x2,h; int c; line(){} line(double xx1,double xx2,double yy1,int cc): x1(xx1),x2(xx2),h(yy1),c(cc){} }s[maxn]; bool clm(line x,line y) { return x.h<y.h; } struct node { int l,r; double len,len1;//len是该区间覆盖>1次的长度,len1是该区间覆盖等于一次的长度 int c; }tree[maxn*4]; double x[maxn]; int n; void build(int id,int l,int r) { tree[id].l=l; tree[id].r=r; tree[id].c=0; tree[id].len=tree[id].len1=0.0; if(l!=r) { int mid=(l+r)/2; build(id*2,l,mid); build(id*2+1,mid+1,r); } } void pushup(int id,int l,int r) { //先处理覆盖一次的长度 if(tree[id].c)tree[id].len1=x[r]-x[l-1];//若tree[id].c>=1说明该区间完全覆盖 else if(l==r)tree[id].len1=0.0; else tree[id].len1=tree[id*2].len1+tree[id*2+1].len1;//若tree[id].c==0,覆盖一次的长度就左右儿子被覆盖一次的长度 //再处理覆盖两次以上的长度 if(tree[id].c>1) tree[id].len=x[r]-x[l-1]; else if(l==r)tree[id].len=0.0; else if(tree[id].c==1)//若tree[id].c==1,只能说明该区间没有被完全覆盖两次以上,有可能它的儿子覆盖了两次 tree[id].len=tree[id*2].len1+tree[id*2+1].len1;//去儿子节点覆盖了一次的长度 else tree[id].len=tree[id*2].len+tree[id*2+1].len;//若tree[id].c==0它被覆盖了0次,但是它儿子可能被覆盖了两次以上, //则去它儿子被覆盖两次以上的长度 } void update(int id,int l,int r,int c) { //if(l<=tree[id].l&&tree[id].r<=r) if(l==tree[id].l&&tree[id].r==r) { tree[id].c+=c; pushup(id,tree[id].l,tree[id].r); } else { int mid=(tree[id].l+tree[id].r)/2; if(r<=mid)update(id*2,l,r,c); else if(l>mid)update(id*2+1,l,r,c); else { update(id*2,l,mid,c); update(id*2+1,mid+1,r,c); } // if(l<=mid)update(id*2,l,r,c); // if(r>mid)update(id*2+1,l,r,c); pushup(id,tree[id].l,tree[id].r); } } int main() { int i,k,t; double x1,x2,y1,y2; scanf("%d",&t); while(t--) { scanf("%d",&n); k=0; for(i=0;i<n;i++) { scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); s[k]=line(x1,x2,y1,1); x[k]=x1; k++; s[k]=line(x1,x2,y2,-1); x[k]=x2; k++; } sort(s,s+k,clm); sort(x,x+k); int m=1; for(i=1;i<k;i++) { if(x[i]!=x[i-1]) x[m++]=x[i]; } build(1,1,m-1); double ans=0.0; for(i=0;i<k-1;i++) { int l=lower_bound(x,x+m-1,s[i].x1)-x; int r=lower_bound(x,x+m-1,s[i].x2)-x; update(1,l+1,r,s[i].c); ans+=tree[1].len*(s[i+1].h-s[i].h); } printf("%0.2f\n",ans); } return 0; }
相关文章推荐
- Bat总结
- Codeforces 480C Riding in a Lift dp
- 油田 Oil Deposits
- Popup window
- `which useradd`命令示例
- PHP实现的迷你漂流瓶
- ReactiveCocoa与Functional Reactive Programming
- Jquery ajax basic
- hdu5317(2015多校3)--RGCDQ(素数筛+枚举)
- C#解惑29: 循环者的新娘
- zoj 3450Doraemon's Railgun
- C#解惑30: 循环者的爱子
- python提取隐含结构的字符串
- Android Material Design之Toolbar与Palette实践
- MySQL要导出成excel的方法
- ARX创建新图层,设置颜色,并置为当前图层
- STL
- ios8tableView分割线左边空白问题
- 在Ubuntu 14.04安装和使用Docker
- Qt5.4.1移植到arm——Linuxfb篇