HDU 1255 矩形面积交

来源:互联网 发布:淘宝可以寄到美国吗 编辑:程序博客网 时间:2024/04/29 20:42

【题意】给了N个矩形,求出其中被覆盖了两次及两次以上的小矩形的面积总和!

【分析】这里相对于面积并来说,主要是要增加一个统计区间被覆盖了1次及一次以上,以及2次及2次以上的区间长度!

【AC代码】

#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>using namespace std;const int maxn = 15000;struct seg{    double y,x1,x2,k;    seg(){}    seg(double y,double x1,double x2,double k):y(y),x1(x1),x2(x2),k(k){}    bool operator<(const seg &rhs) const{        return y<rhs.y;    }}s[maxn*3];double Hash[maxn*4];struct node{    int l,r,flag;    double len1,len2; //len1表示区间被覆盖一次或者以上的长度,len2表示区间被覆盖两次及以上的长度}Tree[maxn*4];int binary(int l,int r,double val){    while(l<=r){        int m = (l+r)>>1;        if(Hash[m]==val) return m;        else if(Hash[m]<val) l=m+1;        else r=m-1;    }    return -1;}void Build(int l,int r,int rt){    Tree[rt].l=l,Tree[rt].r=r,Tree[rt].flag=0;    Tree[rt].len1=Tree[rt].len2=0;    if(l==r) return ;    int m = (l+r)>>1;    Build(l,m,rt<<1);    Build(m+1,r,rt<<1|1);}void Push_Up(int rt){//主要是pushup,按照kuangbin的模板整的    if(Tree[rt].flag>=2){        Tree[rt].len1 = Tree[rt].len2 = Hash[Tree[rt].r+1]-Hash[Tree[rt].l];    }else if(Tree[rt].flag==1){        if(Tree[rt].l==Tree[rt].r){            Tree[rt].len1 = Hash[Tree[rt].r+1]-Hash[Tree[rt].l];            Tree[rt].len2 = 0;        }else{            Tree[rt].len1 = Hash[Tree[rt].r+1]-Hash[Tree[rt].l];            Tree[rt].len2 = Tree[rt<<1].len1+Tree[rt<<1|1].len1;        }    }else{        if(Tree[rt].l==Tree[rt].r){            Tree[rt].len1=Tree[rt].len2=0;        }else{            Tree[rt].len1 = Tree[rt<<1].len1+Tree[rt<<1|1].len1;            Tree[rt].len2 = Tree[rt<<1].len2+Tree[rt<<1|1].len2;        }    }}void Update(int L,int R,double val,int rt){    if(L<=Tree[rt].l&&Tree[rt].r<=R){        Tree[rt].flag+=val;        Push_Up(rt);        return ;    }    int m = (Tree[rt].l+Tree[rt].r)>>1;    if(L<=m) Update(L,R,val,rt<<1);    if(m<R)  Update(L,R,val,rt<<1|1);    Push_Up(rt);}int main(){    int T,n,m,k;    double x1,y1,x2,y2;    scanf("%d",&T);    while(T--){        scanf("%d",&n);        m=0;        while(n--){            //cin>>x1>>y1>>x2>>y2;            scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);            s[m] = seg(y1,x1,x2,1);            Hash[m++] = x1;            s[m] = seg(y2,x1,x2,-1);            Hash[m++] = x2;        }        sort(Hash,Hash+m);        sort(s,s+m);        k = 1;        Hash[0] = Hash[0];         for(int i=1; i<m; i++) if(Hash[i]!=Hash[i-1]) Hash[k++] = Hash[i];        Build(0,k-1,1);        double ans = 0;        for(int i=0; i<m; i++){            int L = binary(0,k-1,s[i].x1);            int R = binary(0,k-1,s[i].x2)-1;            Update(L,R,s[i].k,1);            ans += Tree[1].len2*(s[i+1].y-s[i].y);        }        printf("%.2lf\n",ans);    }    return 0;}


1 0