HDU 1255 覆盖的面积 线段树+扫描线求面积并
2015-08-09 19:37
531 查看
基本和上一题类似...只是push_up函数中多了一部分东西,len1代表被至少覆盖一次的长度,len2代表至少被覆盖两次的长度。一段区间内被覆盖两次的长度有三种情况,一种是整个区间都被覆盖了两次,另外一个是整个区间被覆盖一次,然后左右孩子也有部分被覆盖一次的经历...还有就是左右孩子有部分被覆盖两次...然后和上一题基本不变..
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<set> #include<vector> #include<iterator> #include<map> using namespace std; #define LL long long vector<double> v; vector<double>::iterator it1; struct node { int l,r,cover; double len1,len2; }data[20000]; struct lin { double yu,yd,x; int cover; }line[20000]; int cmp(lin a,lin b) { return a.x<b.x; } void build(int l,int r,int k) { data[k].l=l; data[k].r=r; data[k].len1=data[k].len2=0; data[k].cover=0; if(l+1==r) return ; int mid=(l+r)/2; build(l,mid,k*2); build(mid,r,k*2+1); } void push_up(int k) { if(data[k].cover) data[k].len1=v[data[k].r]-v[data[k].l]; else if(data[k].l+1==data[k].r) data[k].len1=0; else data[k].len1=data[k*2].len1+data[k*2+1].len1; if(data[k].cover>1) data[k].len2=v[data[k].r]-v[data[k].l]; else if(data[k].l+1==data[k].r) data[k].len2=0; else if(data[k].cover==1) data[k].len2=data[k*2].len1+data[k*2+1].len1; else data[k].len2=data[k*2].len2+data[k*2+1].len2; } void updata(int l,int r,int k,int x) { if(data[k].l>r || data[k].r<l) return; if(data[k].l>=l&&data[k].r<=r) { data[k].cover+=x; push_up(k); return ; } updata(l,r,k*2,x); updata(l,r,k*2+1,x); push_up(k); } int main() { int n; int t; scanf("%d",&t); while(t--) { v.clear(); v.push_back(-1); scanf("%d",&n); int m=0; double x1,x2,y1,y2; for(int i=0;i<n;i++) { scanf("%lf %lf %lf %lf",&x1,&y1,&x2,&y2); v.push_back(y1); line[m].cover=1; line[m].yd=y1; line[m].yu=y2; line[m].x=x1; m++; v.push_back(y2); line[m].cover=-1; line[m].yd=y1; line[m].yu=y2; line[m].x=x2; m++; } sort(v.begin(),v.end()); it1=unique(v.begin(),v.end()); v.erase(it1,v.end()); int k=v.size(); build(1,k-1,1); sort(line,line+m,cmp); double ans=0; for(int i=0;i<m-1;i++) { int x=lower_bound(v.begin(),v.end(),line[i].yd)-v.begin(); int y=lower_bound(v.begin(),v.end(),line[i].yu)-v.begin(); updata(x,y,1,line[i].cover); ans+=data[1].len2*(line[i+1].x-line[i].x); } printf("%0.2f\n",ans); } return 0; }
相关文章推荐
- linux shell学习
- app 摇一摇功能
- OC中多态
- 35 Search Insert Position
- 常见OJ评判结果对照表,作为ACMer你懂得!【转】
- Program B--CodeForces 492B
- php框架laravel学习 三 (基本功能)
- spring的@Transactional注解详细用法
- 知识图谱,为移动搜索而生
- UVA 11270 Tiling Dominoes(轮廓线DP经典)
- 单例singleton
- SQL Server 2005为数据库设置用户名和密码的方法
- Java字符串题目--删除给定字符串中出现次数最少的字符
- 开发一个Servlet程序及对Servlet的一些思考
- c语言中的函数
- C# 与MySQL
- android多线程断点续传下载
- 一致性哈希算法与Java实现
- OC中继承和复合
- 在前端设计响应式设计