给定N个多边形,然后每次查询一段坐标内图形的面积。
这里线段树是要离散化的,所以下传标记找mid高度时,要注意不是线段树区间的中点,而是实际区间的中点,
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<cstdlib>
using namespace std;
const int N=125005;
struct point{int x,y;};
int n;
int b[N],nn;
struct aa
{
int l,r;
double lh,rh,len,sum;
}a[N*4];
void build(int i,int l,int r)
{
a[i].len=b[r+1]-b[l];
a[i].sum=a[i].lh=a[i].rh=0;
a[i].l=l,a[i].r=r;
if (l==r) return ;
int mid=(l+r)>>1;
build(i<<1,l,mid);
build(i<<1|1,mid+1,r);
}
void up(int i) {a[i].sum=a[i<<1].sum+a[i<<1|1].sum;}
void down(int i)
{
int l=i<<1,r=i<<1|1;
if (a[i].lh!=0||a[i].rh!=0)
{
double midh=a[i].lh+(a[i].rh-a[i].lh)*(a[l].len/a[i].len);
a[l].sum+=(a[i].lh+midh)*a[l].len/2;
a[r].sum+=(midh+a[i].rh)*a[r].len/2;
a[l].lh+=a[i].lh,a[l].rh+=midh;
a[r].lh+=midh,a[r].rh+=a[i].rh;
a[i].lh=a[i].rh=0;
}
}
void add(int i,int l,int r,double lh,double rh)
{
if (a[i].l==l&&a[i].r==r)
{
a[i].sum+=a[i].len*(lh+rh)/2;
a[i].lh+=lh,a[i].rh+=rh;
return ;
}
down(i);
int mid=(a[i].l+a[i].r)>>1;
if (r<=mid) add(i<<1,l,r,lh,rh);
else if (mid<l) add(i<<1|1,l,r,lh,rh);
else
{
double midh=lh+(rh-lh)*(double(b[mid+1]-b[l])/double(b[r+1]-b[l]));
add(i<<1,l,mid,lh,midh);
add(i<<1|1,mid+1,r,midh,rh);
}
up(i);
}
double query(int i,int l,int r)
{
if (a[i].l==l&&a[i].r==r) return a[i].sum;
down(i);
int mid=(a[i].l+a[i].r)>>1;
if (r<=mid) return query(i<<1,l,r);
else if (mid<l) return query(i<<1|1,l,r);
return query(i<<1,l,mid)+query(i<<1|1,mid+1,r);
}
struct QUE
{
int op,num,l,r;
point p[5];
}Q[25005];
inline int pos(int x) {return lower_bound(b+1,b+nn+1,x)-b;}
void work()
{
scanf("%d",&n);
char ch[2];
nn=0;
for (int i=1;i<=n;i++)
{
scanf("%s",ch);
if (ch[0]=='R')
{
Q[i].op=1;
scanf("%d",&Q[i].num);
for (int j=0;j<Q[i].num;j++) scanf("%d%d",&Q[i].p[j].x,&Q[i].p[j].y),b[++nn]=Q[i].p[j].x;
}
else Q[i].op=2,scanf("%d%d",&Q[i].l,&Q[i].r),b[++nn]=Q[i].l,b[++nn]=Q[i].r;
}
sort(b+1,b+nn+1);
nn=unique(b+1,b+nn+1)-b-1;
build(1,1,nn-1);
for (int i=1;i<=n;i++)
{
QUE &t=Q[i];
if (t.op==1)
{
for (int r,l=0;l<t.num;l++)
{
r=(l+1)%t.num;
if (t.p[r].x>t.p[l].x) add(1,pos(t.p[l].x),pos(t.p[r].x)-1,-t.p[l].y,-t.p[r].y);
else add(1,pos(t.p[r].x),pos(t.p[l].x)-1,t.p[r].y,t.p[l].y);
}
}
else printf("%.3lf\n",query(1,pos(t.l),pos(t.r)-1));
}
}
int main()
{
int T;
scanf("%d",&T);
while (T--) work();
return 0;
}