hdu4419 Colourful Rectangle

来源:互联网 发布:excel文档解密软件 编辑:程序博客网 时间:2024/06/07 11:05

用扫描线扫一下,同时用线段树维护添加及删除的线段信息就好。
因为只需要检查根的信息就足够了,所以这棵线段树其实只需要上传信息。用0,1,…7八个数记录节点的不同颜色的覆盖情况,每次上传时根据子节点的信息及父节点的覆盖情况算出父节点的信息即可。

#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>using namespace std;typedef long long ll;#define clr(a) memset(a,0,sizeof(a))struct nd{    int l,r,x[5];    ll le[8];}tre[100010];ll dr[20010];int dn;void gentre(int l,int r,int ni){    nd&p=tre[ni];    clr(p.le),clr(p.x);    p.l=l,p.r=r;    if(l==r)        p.le[0]=dr[r+1]-dr[l];    else{        int m=(l+r)>>1;        gentre(l,m,ni<<1),gentre(m+1,r,ni<<1|1);        p.le[0]=dr[r+1]-dr[l];    }};void _upd(int ni){    nd&p=tre[ni];    int x=(p.x[1]?1:0)|(p.x[2]?2:0)|(p.x[4]?4:0),i;    if(p.l==p.r){        clr(p.le);        p.le[x]=dr[p.r+1]-dr[p.l];    }    else{        nd&l=tre[ni<<1],&r=tre[ni<<1|1];        ll t[8];        for(i=0;i<8;++i)t[i]=l.le[i]+r.le[i];        for(clr(p.le),i=0;i<8;++i)            p.le[i|x]+=t[i];    }};void upd(int l,int r,int x,int cx,int ni){    nd&p=tre[ni];    if(p.l==l&&p.r==r){        p.x[x]+=cx;        _upd(ni);    }    else{        int m=(p.l+p.r)>>1;        if(r<=m)            upd(l,r,x,cx,ni<<1);        else if(l>m)            upd(l,r,x,cx,ni<<1|1);        else            upd(l,m,x,cx,ni<<1),upd(m+1,r,x,cx,ni<<1|1);        _upd(ni);    }};struct ti{    ll a,b,c;    int x,cx;}tr[20010];bool timp(const ti&a,const ti&b){    return a.c<b.c;};inline int _ts(char x){    return x=='R'?1:x=='G'?2:4;};int bfi(ll x){    int b=0,e=dn-1,m;    while(1){        m=(b+e)>>1;        if(dr[m]==x)            return m;        else if(dr[m]<x)            b=m+1;        else            e=m-1;    }};int ct=0,n;char cz[5];ll rs[8];int _opt[]={1,2,4,3,5,6,7};void cl(){    int i,j,k;ll a,b,c,d;    scanf("%d",&n);    for(i=j=0;i<n;++i){        scanf("%s %I64d %I64d %I64d %I64d",cz,&a,&b,&c,&d);        tr[j].a=b,tr[j].b=d,tr[j].c=a,tr[j].cx=1,tr[j].x=_ts(cz[0]);        dr[j++]=b;        tr[j].a=b,tr[j].b=d,tr[j].c=c,tr[j].cx=-1,tr[j].x=_ts(cz[0]);        dr[j++]=d;    }    n<<=1;    sort(dr,dr+n),sort(tr,tr+n,timp);    dn=unique(dr,dr+n)-dr;    gentre(0,dn-2,1);    for(i=0;i<n&&tr[i].c==tr[0].c;++i)        upd(bfi(tr[i].a),bfi(tr[i].b)-1,tr[i].x,tr[i].cx,1);    for(clr(rs);i<n;){        for(j=0;j<8;++j)            rs[j]+=tre[1].le[j]*(tr[i].c-tr[i-1].c);        for(j=i;i<n&&tr[i].c==tr[j].c;++i)            upd(bfi(tr[i].a),bfi(tr[i].b)-1,tr[i].x,tr[i].cx,1);    }    for(printf("Case %d:\n",++ct),i=0;i<7;printf("%I64d\n",rs[_opt[i++]]));};int main(){#ifndef ONLINE_JUDGE    freopen("in.txt","r",stdin);    freopen("out.txt","w",stdout);#endif    int t;scanf("%d",&t);    while(t--)        cl();    return 0;};
0 0