您的位置:首页 > 大数据 > 人工智能

ural 1019 Line Painting (线段树)

2013-08-05 16:33 281 查看
#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:b

struct point{
    int m,f,n;
}p
;
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
;
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
.m=i;   p
.f=0;   p
.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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: