HDU 1199 Color the Ball

第一个离散化线段树
 
先把区间写成左开右闭的形式,然后sort() unique() lower_bound() 离散化
最后按普通线段树更新即可
 
代码:
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define for if(0); else for
const int N=2010;

struct Inteval{
    int l,r;
    char color;
    Inteval(){l=r=0,color='b';}
    Inteval(int l,int r){
        this->l=l;
        this->r=r;
        color='b';
    }
};


struct SegNode{
    int lc,rc,cc,pc;
    char empty,color;
    SegNode(){lc=rc=cc=pc=empty=color=0;}
};

struct SegTree{
    SegNode a[N<<2];
    int Q,len[N<<2];
    void Init(int n){
        for(Q=1;Q<=n+2;Q<<=1) ;
        memset(a,0,sizeof(a));
        memset(len,0,sizeof(len));
    }

    void update_len(int p,int l){
        p+=Q;
        while(p) len[p]+=l,p>>=1;
    }

    void update_node(int rt,int color){
        int v=color==1?len[rt]:0;
        a[rt].color=color;
        a[rt].lc=a[rt].rc=a[rt].cc=v;
        a[rt].pc=0;
    }

    SegNode merge(SegNode l,SegNode r,int llen,int rlen,int L)const {
        SegNode ret;
        ret.lc=l.lc;
        ret.rc=r.rc;
        ret.cc=l.cc;
        ret.pc=l.pc;
        if(l.rc+r.lc>ret.cc) ret.cc=l.rc+r.lc,ret.pc=llen-l.rc;
        if(r.cc>ret.cc) ret.cc=r.cc,ret.pc=r.pc+llen;
        if(l.lc==llen) ret.lc+=r.lc;
        if(r.rc==rlen) ret.rc+=l.rc;
        ret.color=l.color==r.color?l.color:-1;
        return ret;
    }

    void pushup(int rt,int llen,int rlen,int L){
        a[rt]=merge(a[rt<<1],a[rt<<1|1],llen,rlen,L);
    }
    void pushdown(int rt,int llen,int rlen,int L){
        if(a[rt].color!=-1){
            a[rt<<1].color=a[rt<<1|1].color=a[rt].color;
            update_node(rt<<1,a[rt].color);
            update_node(rt<<1|1,a[rt].color);
        }
    }

    void update(int L,int R,int l,int r,int rt,int color){
        int m=(l+r)>>1;
        if(L<=l && r<=R){
            update_node(rt,color);
            return;
        }
        if(rt>=Q) return;
        pushdown(rt,len[rt<<1],len[rt<<1|1],r-l+1);
        if(L<=m) update(L,R,l,m,rt<<1,color);
        if(m<R) update(L,R,m+1,r,rt<<1|1,color);
        pushup(rt,len[rt<<1],len[rt<<1|1],r-l+1);
    }

}st;


Inteval inteval[N];
int tmp[N<<1],tmpcnt;
int n;




int main() {
    while(scanf("%d",&n)!=EOF){
        for(int i=0;i<n;i++) scanf(" %d %d %c",&inteval[i].l,&inteval[i].r,&inteval[i].color);
        tmpcnt=0;
        for(int i=0;i<n;i++) tmp[tmpcnt++]=inteval[i].l,tmp[tmpcnt++]=inteval[i].r+1;
        sort(tmp,tmp+tmpcnt);
        tmpcnt=unique(tmp,tmp+tmpcnt)-tmp;
        st.Init(tmpcnt);
        for(int i=1;i<tmpcnt;i++) st.update_len(i-1,tmp[i]-tmp[i-1]);
        for(int i=0;i<n;i++){
            int l=lower_bound(tmp,tmp+tmpcnt,inteval[i].l)-tmp;
            int r=lower_bound(tmp,tmp+tmpcnt,inteval[i].r+1)-tmp-1;
            int color=inteval[i].color=='w';
            st.update(l,r,0,st.Q-1,1,color);
        }
        int ans1=st.a[1].pc+tmp[0];
        int ans2=ans1+st.a[1].cc-1;
        if(ans2>0) printf("%d %d\n",ans1,ans2);
        else printf("Oh, my god\n");
    }
    return 0;
}
posted @ 2012-08-15 11:56  编程菜菜  阅读(996)  评论(0编辑  收藏  举报