题目地址:HDU 1255
这题跟面积并的方法很像,只不过需要再加一个变量。
刚开始我以为直接用那个变量就行,只不过判断是否大于0改成判断是否大于1。但是后来发现了个问题,因为这个没有下放,没延迟,比如,在父节点上加了一次1,在该父节点的子节点上又加了一次1,但是这时候所有的结点仍然没有达到2的,但是实际上子节点已经达到2了。这时候可以再加一个变量。那个变量用来保存覆盖数大于等于0的情况,这样的话当计算大于1的覆盖节点的时候,当判断为1的时候就要加上子节点的所有情况,因为字节点是大于0的,加上子节点的说明该父节点也是大于1的。
代码如下:
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include <queue>
#include <map>
#include <set>
#include <algorithm>
using namespace std;
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1
int lazy[10000], cnt;
double sum[10000], c[10000], once[10000];
struct node
{
double l, r, h;
int f;
} edge[100000];
int cmp(node x, node y)
{
return x.h<y.h;
}
void add(double l, double r, double h, int f)
{
edge[cnt].l=l;
edge[cnt].r=r;
edge[cnt].h=h;
edge[cnt++].f=f;
}
void PushUp(int l, int r, int rt)
{
if(lazy[rt]>=2)
{
once[rt]=sum[rt]=c[r+1]-c[l];
}
else if(lazy[rt]==1)
{
once[rt]=c[r+1]-c[l];
if(l==r)
{
sum[rt]=0;
}
else
sum[rt]=once[rt<<1]+once[rt<<1|1];
}
else
{
if(l==r)
once[rt]=sum[rt]=0;
else
{
once[rt]=once[rt<<1]+once[rt<<1|1];
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
}
}
void update(int ll, int rr, int x, int l, int r,int rt)
{
if(ll<=l&&rr>=r)
{
lazy[rt]+=x;
PushUp(l,r,rt);
return ;
}
int mid=l+r>>1;
if(ll<=mid) update(ll,rr,x,lson);
if(rr>mid) update(ll,rr,x,rson);
PushUp(l,r,rt);
}
int erfen(double x, int high)
{
int low=0, mid;
while(low<=high)
{
mid=low+high>>1;
if(c[mid]==x)
return mid;
else if(c[mid]>x)
high=mid-1;
else
low=mid+1;
}
}
int main()
{
int t, n, i, j, k;
double x1, x2, y1, y2, ans;
scanf("%d",&t);
while(t--)
{
ans=0;
memset(sum,0,sizeof(sum));
memset(lazy,0,sizeof(lazy));
memset(once,0,sizeof(once));
scanf("%d",&n);
k=0;
cnt=0;
for(i=0; i<n; i++)
{
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
c[k++]=x1;
c[k++]=x2;
add(x1,x2,y1,1);
add(x1,x2,y2,-1);
}
sort(edge,edge+2*n,cmp);
sort(c,c+k);
for(i=0; i<2*n-1; i++)
{
int l=erfen(edge[i].l,2*n-1);
int r=erfen(edge[i].r,2*n-1);
//printf("%d %d\n",l,r);
update(l,r-1,edge[i].f,0,2*n-1,1);
ans+=sum[1]*(edge[i+1].h-edge[i].h);
//printf("%.2lf %.2lf\n",sum[1],edge[i+1].h-edge[i].h);
}
printf("%.2lf\n",ans);
}
return 0;
}