覆盖的面积 HDU - 1255 面积的交

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/leekerian/article/details/88761588

1.cnt>1 : 说明该区间被覆盖两次或以上,那么长度就可以直接计算,就是该区间的长度

剩下的情况就是cnt=1或cnt=0

2.先看叶子节点,因为是叶子没有孩子了,所以被覆盖两次货以上的长度就是0(无论cnt=1或cnt=0都是0,因为是叶子。。。)

3.不是叶子节点 ,且cnt=1.注意这里,cnt=1确切的意义是什么,应该是,可以确定,这个区间被完全覆盖了1次,而有没有被完全覆盖两次或以上则不知道无法确定,那么怎么怎么办了,只要加上t[lch].s + t[rch].s  即,看看左右孩子区间被覆盖了一次或以上的长度,那么叠加在双亲上就是双亲被覆盖两次或以上的长度

3.不是叶子节点,且cnt=0,确切的意义应该是不完全不知道被覆盖的情况(不知道有没有被覆盖,被覆盖了几次,长度是多少都不知道),这种情况,只能由其左右孩子的信息所得

t[lch].ss + t[rch].ss  , 即直接将左右孩子给覆盖了两次或以上的长度加起来,这样才能做到不重不漏

#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <cstdio>

using namespace std;

#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
const int MAXN=22222;
double sum[MAXN<<2];
int lazy[MAXN<<2];
double sum2[MAXN<<2];

struct Line{
    double l,r,h;
    int s;
    Line(double _l,double _r,double _h,int _s){
        l=_l;
        r=_r;
        h=_h;
        s=_s;
    }
    bool operator <(const struct Line& b)const{
        return h<b.h;
    }
};

vector<double> vt1;
vector<Line> vt2;


void pushup(int l,int r,int rt)
{
    if(lazy[rt]) sum[rt]=vt1[r+1]-vt1[l];
    else if(l==r) sum[rt]=0;
    else sum[rt]=sum[rt<<1]+sum[rt<<1|1];
    if(lazy[rt]>=2) sum2[rt]=vt1[r+1]-vt1[l];
    else if(lazy[rt]==1) sum2[rt]=sum[rt<<1]+sum[rt<<1|1];
    else if(lazy[rt]==0) sum2[rt]=sum2[rt<<1]+sum2[rt<<1|1];
}

void update(int L,int R,int c,int l,int r,int rt)
{
    if(L<=l&&r<=R)
    {
        lazy[rt]+=c;
        pushup(l,r,rt);
        return;
    }
    int mid=(l+r)>>1;
    if(L<=mid) update(L,R,c,lson);
    if(R>mid) update(L,R,c,rson);
    pushup(l,r,rt);
}
int main()
{
    int n;
    scanf("%d",&n);
    while(n--)
    {
        vt1.clear();
        vt2.clear();
        int m;
        scanf("%d",&m);
        for(int i=0;i<m;i++)
        {
            double a,b,c,d;
            scanf("%lf%lf%lf%lf",&a,&b,&c,&d);
            vt1.push_back(a);
            vt1.push_back(c);
            vt2.push_back(Line(a,c,b,1));
            vt2.push_back(Line(a,c,d,-1));
        }
        sort(vt1.begin(),vt1.end());
        sort(vt2.begin(),vt2.end());
        vt1.erase(unique(vt1.begin(),vt1.end()),vt1.end());
        memset(sum,0,sizeof(sum));
        memset(lazy,0,sizeof(lazy));
        memset(sum2,0,sizeof(sum2));
        double ans=0;
        for(int i=0;i<vt2.size()-1;i++)
        {
            int l=lower_bound(vt1.begin(),vt1.end(),vt2[i].l)-vt1.begin();
            int r=lower_bound(vt1.begin(),vt1.end(),vt2[i].r)-vt1.begin()-1;
            update(l,r,vt2[i].s,0,vt1.size()-1,1);
            ans+=sum2[1]*(vt2[i+1].h-vt2[i].h);
        }
        printf("%.2lf\n",ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/leekerian/article/details/88761588
今日推荐