ural 1019 Line Painting (线段树)

来源:互联网 发布:自动顶贴软件 编辑:程序博客网 时间:2024/05/22 00:12


#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define MAX 1000000000#define N 10010#define M 5010#define lch(i) ((i)<<1)#define rch(i) ((i)<<1|1)#define min(a,b) a<b?a:b#define max(a,b) a>b?a:bstruct point{    int m,f,n;}p[N];struct segment{    int l,r,v;}s[M];struct tree{    int l,r,cnt;    int mid()    { return (l+r)>>1; }}t[4*N];int m,num;struct ran{    int l,r;}c[N];int nc;int cmp(struct point a ,struct point b){    return a.n<b.n;}void build(int l ,int r ,int rt){    t[rt].l=l; t[rt].r=r; t[rt].cnt=0;    if(l+1==r) return ;    int mid=t[rt].mid();    build(l,mid,lch(rt));    build(mid,r,rch(rt));}void updata(int l ,int r ,int v ,int rt){    if(t[rt].cnt == v) return ; //剪枝    if(t[rt].l == l && t[rt].r == r)    {        t[rt].cnt=v;        return ;    }    if(t[rt].cnt!=-1) //当前节点是纯色的,传递给它的孩子并且记录其为不纯色的    {        t[lch(rt)].cnt=t[rch(rt)].cnt=t[rt].cnt;        t[rt].cnt=-1;    }    int mid=t[rt].mid();    if(r<=mid)        updata(l,r,v,lch(rt));    else if(l>=mid)        updata(l,r,v,rch(rt));    else    {        updata(l,mid,v,lch(rt));        updata(mid,r,v,rch(rt));    }}void query(int rt){    if(t[rt].cnt==1) //该区间全部是黑色的没必要再继续下去        return ;    if(t[rt].cnt==0) //该区间全部是白色的没必要继续下去,直接记录    {        c[nc].l=t[rt].l-1;        c[nc].r=t[rt].r-1;        nc++;        return ;    }    if(t[rt].l+1==t[rt].r) return ;    //剩下的情况就是为-1的情况无法确定的    query(lch(rt));    query(rch(rt));}void solve(){    build(1,num,1);    for(int i=0; i<m; i++)        updata(s[i].l , s[i].r , s[i].v , 1);     nc=0;    query(1); //统计出所有白色的线段//    for(int i=0; i<nc; i++) printf("[%d,%d]\n",c[i].l,c[i].r);    int maxlen=-1;    int len;    int resl,resr;    int l,r;    l=c[0].l; r=c[0].r;    for(int i=0; i<nc-1; i++)    {        if(c[i+1].l == c[i].r) //可以继续合并一个区间            r=c[i+1].r;        else //第i+1个区间不能合并进来        {            len= p[r].n - p[l].n;            if(len>maxlen)            {                maxlen=len;                resl=l;                resr=r;            }            l=c[i+1].l;            r=c[i+1].r;        }    }    len= p[r].n - p[l].n;    if(len>maxlen)    { resl=l; resr=r; }    printf("%d %d\n",p[resl].n , p[resr].n);}int main(){    while(scanf("%d",&m)!=EOF)    {        m++;        s[0].v=0;        p[0].f=0; p[0].m=0; p[0].n=0;        p[1].f=1; p[1].m=0; p[1].n=MAX;        int n=2;        for(int i=1; i<m; i++)        {            int l,r; char col[5];            scanf("%d%d%s",&l,&r,col);            s[i].v= (col[0]=='b')?1:0;            p[n].m=i;   p[n].f=0;   p[n].n=l;            p[n+1].m=i; p[n+1].f=1; p[n+1].n=r;            n+=2;        }        sort(p,p+n,cmp);        num=0;        for(int i=0; i<n; i++)        {            int mm=p[i].m;            if(i==0 || p[i].n!=p[i-1].n) p[num++]=p[i];            if(p[i].f) s[mm].r=num;            else       s[mm].l=num;        }//        for(int i=0; i<num; i++) printf("%d ",p[i].n); printf("\n");//        for(int i=0; i<m; i++) printf("[%d,%d] %d\n",s[i].l,s[i].r,s[i].v);        solve();    }    return 0;}


原创粉丝点击