线段树扫描线(覆盖两次以上的面积和)hdu1255

来源:互联网 发布:人工智能行业报告 36 编辑:程序博客网 时间:2024/06/06 11:35

为什么加边的那条边是-1会有影响

思路:线段树维护一个twice表示有两条及以上线段覆盖的长度,once表示有一条覆盖的长度

#include<iostream>#include<cstdio>#include<cstring>#include<vector>#include<cmath>#include<queue>#include<stack>#include<map>#include<set>#include<algorithm>using namespace std;const int maxn=2010;int n;double x[maxn];struct seg{    double l,r,h;    int c;    seg(){}    seg(double a,double b,double d,int t):l(a),r(b),h(d),c(t){}    bool operator<(const seg &a)const    {        if(h==a.h)return c>a.c;        return h<a.h;    }}s[maxn];struct IntervalTree{    double once[maxn<<3],twice[maxn<<3];    int cnt[maxn<<3];    void build()    {        memset(cnt,0,sizeof(cnt));        memset(once,0,sizeof(once));        memset(twice,0,sizeof(twice));    }    void maintain(int o,int l,int r)    {        if(cnt[o]>=2)        {            twice[o]=x[r+1]-x[l];            once[o]=0;        }        else if(cnt[o]==1)        {            twice[o]=once[o<<1]+once[o<<1|1]+twice[o<<1]+twice[o<<1|1];            once[o]=x[r+1]-x[l]-twice[o];        }        else        {            twice[o]=twice[o<<1]+twice[o<<1|1];            once[o]=once[o<<1]+once[o<<1|1];        }    }    void update(int o,int l,int r,int q1,int q2,int t)    {        if(q1<=l&&r<=q2)        {            cnt[o]+=t;            maintain(o,l,r);            return ;        }        int mid=(l+r)>>1;        if(q1<=mid)update(o<<1,l,mid,q1,q2,t);        if(q2>mid)update(o<<1|1,mid+1,r,q1,q2,t);        maintain(o,l,r);    }}tree;int main(){    //freopen("in.txt","r",stdin);    int T;    scanf("%d",&T);    while(T--)    {        scanf("%d",&n);        int num=1;        double a,b,c,d;        for(int i=0;i<n;i++)        {            scanf("%lf%lf%lf%lf",&a,&b,&c,&d);            x[num]=a;            s[num++]=seg(a,c,d,-1);            x[num]=c;            s[num++]=seg(a,c,b,1);        }        sort(x+1,x+num);        sort(s+1,s+num);        int nx=unique(x+1,x+num)-x-1;        double ans=0;        tree.build();        for(int i=1;i<num-1;i++)        {            int l=lower_bound(x+1,x+nx+1,s[i].l)-x;            int r=lower_bound(x+1,x+nx+1,s[i].r)-x-1;            tree.update(1,1,nx,l,r,s[i].c);            ans+=tree.twice[1]*(s[i+1].h-s[i].h);        }        printf("%.2f\n",ans);    }    return 0;}


0 0
原创粉丝点击