分析:
求矩形覆盖两次以上的面积…和上一题差不多…
但是计算区间被覆盖长度的时候不太一样…
当当前区间被完全覆盖两次的时候不用多说…如果只被完全覆盖一次呢?…
如果已经被完全覆盖了一次,那么子节点的被覆盖一次的长度现在就变为了当前节点被覆盖两次的长度…
当我看到我输出7.62二然而样例是7.63的时候我整个人都崩溃了…这还卡精度??然后抱着试一试的心态交了一发…A了??……….
代码如下:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
//by NeighThorn
using namespace std;
const int maxn=1000+5;
int cas,n,cnt,tot;
double ans,mp[maxn*2];
struct M{
double x1,x2,y,v;
friend bool operator < (M xx,M yy){
return xx.y<yy.y;
}
}G[maxn*2];
struct Tree{
int l,r,cover;
double lenth,res,res2;
}tree[maxn*2*4];
inline void build(int l,int r,int tr){
tree[tr].l=l,tree[tr].r=r,tree[tr].lenth=mp[r]-mp[l],tree[tr].cover=0,tree[tr].res=tree[tr].res2=0;
if(l+1==r)
return;
int mid=(l+r)>>1;
build(l,mid,tr<<1),build(mid,r,tr<<1|1);
}
inline void change(int l,int r,int val,int tr){
if(tree[tr].l==l&&tree[tr].r==r){
tree[tr].cover+=val;
if(tree[tr].cover>=2)
tree[tr].res=tree[tr].res2=tree[tr].lenth;
else if(tree[tr].cover==1){
tree[tr].res2=tree[tr].lenth;
if(tree[tr].l+1==tree[tr].r)
tree[tr].res=0;
else
tree[tr].res=tree[tr<<1].res2+tree[tr<<1|1].res2;
}
else{
if(tree[tr].l+1==tree[tr].r)
tree[tr].res=tree[tr].res2=0;
else
tree[tr].res2=tree[tr<<1].res2+tree[tr<<1|1].res2,
tree[tr].res=tree[tr<<1].res+tree[tr<<1|1].res;
}
return;
}
int mid=(tree[tr].l+tree[tr].r)>>1;
if(r<=mid)
change(l,r,val,tr<<1);
else if(l>=mid)
change(l,r,val,tr<<1|1);
else
change(l,mid,val,tr<<1),change(mid,r,val,tr<<1|1);
if(tree[tr].cover>=2)
tree[tr].res=tree[tr].res2=tree[tr].lenth;
else if(tree[tr].cover==1){
tree[tr].res2=tree[tr].lenth;
if(tree[tr].l+1==tree[tr].r)
tree[tr].res=0;
else
tree[tr].res=tree[tr<<1].res2+tree[tr<<1|1].res2;
}
else{
if(tree[tr].l+1==tree[tr].r)
tree[tr].res=tree[tr].res2=0;
else
tree[tr].res2=tree[tr<<1].res2+tree[tr<<1|1].res2,
tree[tr].res=tree[tr<<1].res+tree[tr<<1|1].res;
}
}
signed main(void){
scanf("%d",&cas);
double x1,y1,x2,y2;
while(cas--){tot=cnt=0;
scanf("%d",&n);ans=0;
for(int i=1;i<=n;i++)
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2),
G[++tot].x1=x1,G[tot].x2=x2,G[tot].y=y1,G[tot].v=1,
G[++tot].x1=x1,G[tot].x2=x2,G[tot].y=y2,G[tot].v=-1,
mp[++cnt]=x1,mp[++cnt]=x2;
sort(G+1,G+tot+1),sort(mp+1,mp+cnt+1);
int len=unique(mp+1,mp+cnt+1)-mp-1;build(1,len,1);
for(int i=1;i<=tot;i++){
int lala=lower_bound(mp+1,mp+len+1,G[i].x1)-mp;
int lalala=lower_bound(mp+1,mp+len+1,G[i].x2)-mp;
ans+=tree[1].res*(G[i].y-G[i-1].y),
change(lala,lalala,G[i].v,1);
}
printf("%.2f\n",ans);
}
return 0;
}
by >_< NeighThorn