题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1301
思路:线段树染色问题,需要离散化
注意(1)首先是离散的问题,果然自己好渣,1 10 w 1 3 b 7 10 b 如果简单的把1 3 7 10离散化为1 2 3 4 上述的样例结果就为oh my god,其实应该是4 6;
所以傻逼的一想之后我就在离散两个不相邻的书的时候加入一个数离散化为1 2 3 6 7 9 10 ,但是结果为6 6,呵呵啦;
所以只能用最笨的一种办法,将 a,a-1,a+1全部离散化,数据离散化为1 2 3 4 6 7 8 9 10,终于出现了4 6;(群巨讲了另外一种方法,左闭右开啥的,一会儿滚去学)
(2)如果n=0,那么正常情况建树会出错
然后就到了,zoj可以把人逼疯的一点了,a可能比b大,因为这个,我拿到了近10个SF,呵呵呵呵啦
不信就自己试一下
<span style="white-space:pre"> </span>for(i=0;i<n;i++)
{
scanf("%d%d%s",&t[i*2],&t[i*2+1],s);
data[i].x=t[i*2];
data[i].y=t[i*2+1];
if(data[i].x>data[i].y)
while(1);
if(s[0]=='w')
data[i].c=1;
else
data[i].c=0;
}
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define max(a,b) ((a)>(b)? (a):(b))
#define min(a,b) ((a)<(b)? (a):(b))
const int N=2005;
int t[N*2],tp[N*6],cnt,ans,tmp,st,an,anst;
struct ty
{
int x,y,c;
}data[N];
struct node
{
int l,r,col;
}d[12010<<3];
int find(int x)
{
int l=1,r=cnt-1,mid;
while(l<=r)
{
mid=(l+r)>>1;
if(tp[mid]<x)
l=mid+1;
else if(tp[mid]>x)
r=mid-1;
else
return mid;
}
return -1;
}
void pushdown(int rt)
{
d[rt<<1].col=d[rt<<1|1].col=d[rt].col;
d[rt].col=-1;
}
void pushup(int rt)
{
if(d[rt<<1].col!=-1&&d[rt<<1].col==d[rt<<1|1].col)
d[rt].col=d[rt<<1].col;
}
void build (int rt,int L,int R)
{
d[rt].l=L;
d[rt].r=R;
d[rt].col=0;
if(L>=R)
return ;
int mid=(L+R)>>1;
build(rt<<1,L,mid);
build(rt<<1|1,mid+1,R);
}
void updata(int rt,int L,int R,int a)
{
if(d[rt].l==L&&d[rt].r==R)
{
if(d[rt].col!=a)
d[rt].col=a;
return ;
}
if(d[rt].col!=-1&&d[rt].col!=a)
pushdown(rt);
int mid=(d[rt].l+d[rt].r)>>1;
if(R<=mid)
updata(rt<<1,L,R,a);
else if(L>mid)
updata(rt<<1|1,L,R,a);
else
{
updata(rt<<1,L,mid,a);
updata(rt<<1|1,mid+1,R,a);
}
pushup(rt);
}
void query(int rt)
{
if(d[rt].col==1)
{
if(tmp==0)
st=d[rt].l;
tmp+=d[rt].r-d[rt].l+1;
return ;
}
if(d[rt].col==0)
{
an=tp[st+tmp-1]-tp[st]+1;
if(an>ans)
{
anst=st;
ans=an;
}
tmp=0;
return ;
}
if(d[rt].col==-1)
{
query(rt<<1);
query(rt<<1|1);
}
}
int main()
{
int i,n,a,b;
char s[3];
//freopen("in.txt","r",stdin);
while(scanf("%d",&n)!=EOF)
{
if(n==0)
{
printf("Oh, my god\n");
continue;
}
for(i=0;i<n;i++)
{
scanf("%d%d%s",&t[i*2],&t[i*2+1],s);
data[i].x=min(t[i*2],t[i*2+1]);
data[i].y=max(t[i*2],t[i*2+1]);
if(s[0]=='w')
data[i].c=1;
else
data[i].c=0;
}
sort(t,t+n*2);
cnt=1;
tp[cnt++]=t[0];
for(i=1;i<n*2;i++)
{
if(t[i]-t[i-1]>2)
tp[cnt++]=t[i-1]+1;
if(t[i]-t[i-1]>1)
tp[cnt++]=t[i]-1;
if(t[i]-t[i-1]>0)
tp[cnt++]=t[i];
}
//for(i=1;i<cnt;i++) printf("%d ",tp[i]); printf("\n");
build(1,1,cnt-1);
for(i=0;i<n;i++)
{
a=find(data[i].x);
b=find(data[i].y);
//printf("%d %d %d\n",a,b,data[i].c);
updata(1,a,b,data[i].c);
}
//for(i=1;i<=17;i++) printf("%d d[i].l=%d d[i].r=%d d[i].col=%d\n",i,d[i].l,d[i].r,d[i].col);
tmp=0;ans=0;
query(1);
an=tp[st+tmp-1]-tp[st]+1;
if(an>ans)
{
anst=st;
ans=an;
}
if(ans==0)
printf("Oh, my god\n");
else
printf("%d %d\n",tp[anst],tp[anst]+ans-1);
}
return 0;
}