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;
}