标签:
题目大意:给若干个矩形,统计重叠次数不为0的面积。
题目分析:维护扫描线的长度时,只需要只统计覆盖次数大于1的区间即可。这是个区间更新,不过不能使用懒标记,但是数据规模不大,不用懒惰标记仍可以AC。
代码如下:
# include<iostream> # include<cstdio> # include<map> # include<vector> # include<cstring> # include<algorithm> using namespace std; # define mid (l+(r-l)/2) const int N=1000; void read(int &x) { x=0; char c; while((c=getchar())&&(c<‘0‘||c>‘9‘)); x=c-‘0‘; while(c=getchar()){ if(c<‘0‘||c>‘9‘) break; x=x*10+c-‘0‘; } } //***************************************** struct Node { int c; double len; }; struct Segment { double x1,x2,y; int d; }; Segment seg[N*2+5]; map<double,int>mp; vector<double>v; Node tr[(N<<3)+5]; bool comp(const Segment &s1,const Segment &s2) { return s1.y<s2.y; } void pushUp(int rt) { tr[rt].len=tr[rt<<1].len+tr[rt<<1|1].len; } void build(int rt,int l,int r) { tr[rt].c=0; tr[rt].len=0.0; if(l==r) return ; build(rt<<1,l,mid); build(rt<<1|1,mid+1,r); } void update(int rt,int l,int r,int L,int R,int d) { if(l==r){ tr[rt].c+=d; if(tr[rt].c>1) tr[rt].len=v[r]-v[l-1]; else tr[rt].len=0; }else{ if(L<=mid) update(rt<<1,l,mid,L,R,d); if(R>mid) update(rt<<1|1,mid+1,r,L,R,d); pushUp(rt); } } int main() { //freopen("in.txt","r",stdin); int T,n; read(T); while(T--) { read(n); v.clear(); mp.clear(); double x1,x2,y1,y2; for(int i=0;i<n;++i){ scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); seg[i<<1].x1=seg[i<<1|1].x1=x1; seg[i<<1].x2=seg[i<<1|1].x2=x2; seg[i<<1].y=y1,seg[i<<1|1].y=y2; seg[i<<1].d=1,seg[i<<1|1].d=-1; v.push_back(x1); v.push_back(x2); } n<<=1; sort(seg,seg+n,comp); sort(v.begin(),v.end()); int m=unique(v.begin(),v.end())-v.begin(); for(int i=0;i<m;++i) mp[v[i]]=i+1; seg[n].y=seg[n-1].y; build(1,1,m-1); double ans=0.0; for(int i=0;i<n;++i){ update(1,1,m-1,mp[seg[i].x1],mp[seg[i].x2]-1,seg[i].d); ans+=tr[1].len*(seg[i+1].y-seg[i].y); //cout<<tr[1].len<<endl; } printf("%.2lf\n",ans); } return 0; }
标签:
原文地址:http://www.cnblogs.com/20143605--pcx/p/5750126.html