这个题要求求多边形的面积,参考了http://www.cnblogs.com/staginner/archive/2012/04/13/2446528.html这个博客,除了感叹方法巧妙外,又一次理解了扫描线。
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=25100*5;
const int maxm=maxn*4;
struct Ins
{
char op[3];
int cnt;
int x[6],y[6];
}a[25100];
struct Node
{
int l;
int r;
double s;
double sl;
double sr;
bool isupdate;
}t[maxm];
int n,X[maxn],cntx;
void Build(int l,int r,int index)
{
t[index].l=l;
t[index].r=r;
t[index].s=t[index].isupdate=t[index].sl=t[index].sr=0;
if(l==r)
return;
int mid=(l+r)>>1;
Build(l,mid,index<<1);
Build(mid+1,r,index<<1|1);
}
double Cal(double sl,double sr,int x1,int x2)
{
return (sl*x2+sr*x1)/(x1+x2);
}
void PushUp(int index)
{
t[index].s=t[index<<1].s+t[index<<1|1].s;
}
void PushDown(int index)
{
double midh=Cal(t[index].sl,t[index].sr,X[t[index<<1].r+1]-X[t[index<<1].l],X[t[index<<1|1].r+1]-X[t[index<<1|1].l]);
t[index<<1].sl+=t[index].sl;
t[index<<1].sr+=midh;
t[index<<1].s+=(midh+t[index].sl)*(X[t[index<<1].r+1]-X[t[index<<1].l])/2;
t[index<<1|1].sl+=midh;
t[index<<1|1].sr+=t[index].sr;
t[index<<1|1].s+=(midh+t[index].sr)*(X[t[index<<1|1].r+1]-X[t[index<<1|1].l])/2;
t[index<<1].isupdate=t[index<<1|1].isupdate=true;
t[index].isupdate=t[index].sl=t[index].sr=0;
}
void Update(int l,int r,int index,double y1,double y2)
{
if(l>r)
return;
if(t[index].l==l&&t[index].r==r)
{
t[index].s+=(y1+y2)*(X[r+1]-X[l])/2;
t[index].sl+=y1;
t[index].sr+=y2;
t[index].isupdate=true;
return;
}
if(t[index].isupdate)
PushDown(index);
int mid=(t[index].l+t[index].r)>>1;
if(r<=mid)
Update(l,r,index<<1,y1,y2);
else if(l>mid)
Update(l,r,index<<1|1,y1,y2);
else
{
double midh=Cal(y1,y2,X[mid+1]-X[l],X[r+1]-X[mid+1]);
Update(l,mid,index<<1,y1,midh);
Update(mid+1,r,index<<1|1,midh,y2);
}
PushUp(index);
}
double Query(int l,int r,int index)
{
if(l>r)
return 0;
if(t[index].l==l&&t[index].r==r)
return t[index].s;
int mid=(t[index].l+t[index].r)>>1;
if(t[index].isupdate)
PushDown(index);
double ans=0;
if(r<=mid)
return Query(l,r,index<<1);
else if(l>mid)
return Query(l,r,index<<1|1);
else
return Query(l,mid,index<<1)+Query(mid+1,r,index<<1|1);
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
cntx=0;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%s",&a[i].op);
if(a[i].op[0]=='R')
{
scanf("%d",&a[i].cnt);
for(int j=0;j<a[i].cnt;j++)
{
scanf("%d%d",&a[i].x[j],&a[i].y[j]);
X[cntx++]=a[i].x[j];
}
}
else
{
scanf("%d%d",&a[i].x[0],&a[i].x[1]);
a[i].cnt=1;
X[cntx++]=a[i].x[0];
X[cntx++]=a[i].x[1];
}
}
sort(X,X+cntx);
cntx=unique(X,X+cntx)-X;
Build(0,cntx,1);
for(int i=0;i<n;i++)
{
if(a[i].op[0]=='R')
{
bool isback=false;
for(int j=0;j<a[i].cnt;j++)
{
int sl=lower_bound(X,X+cntx,a[i].x[j])-X;
int sr=lower_bound(X,X+cntx,a[i].x[(j+1)%a[i].cnt])-X;
if(sr<sl)
isback=true;
if(!isback)
Update(sl,sr-1,1,-a[i].y[j],-a[i].y[(j+1)%a[i].cnt]);
else
Update(sr,sl-1,1,a[i].y[(j+1)%a[i].cnt],a[i].y[j]);
}
}
else
{
int sl=lower_bound(X,X+cntx,a[i].x[0])-X;
int sr=lower_bound(X,X+cntx,a[i].x[1])-X;
sr--;
printf("%.3f\n",Query(sl,sr,1));
}
}
}
return 0;
}