真你妹。。。。
周末就写了三个题竟然有两个超时。。。
周一下午来了让qyf看,然后第一个是因为并查集没代劳写路径压缩所以挂了,这个还算比较好的。。。
这个题更火,因为没代劳把字符串的长度保存到变量里,每次直接调用strlen然后超时,qyf让我改我没理他,然后改完就过了!!!
一个程序就因为多调用了几次strlen所以从100变成了20啊我X!!!
不吐槽了。。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define MAX 250010
#define ll long long
using namespace std;
int tot,a[MAX],size[MAX],child[MAX][2],father[MAX],value[MAX],root;
ll w[MAX];
char s[MAX];
long long pow[MAX]={1};
int len;
void update(int x)
{
size[x]=size[child[x][0]]+size[child[x][1]]+1;
w[x]=(w[child[x][0]]*pow[size[child[x][1]]+1]+value[x]*pow[size[child[x][1]]]+w[child[x][1]])%1000000007;
}
void build(int &x,int l,int r)
{
if(l>r)
{
x=0;
return;
}
int mid=(l+r)>>1;
x=++tot;
size[x]=1;
value[x]=a[mid];
build(child[x][0],l,mid-1);
build(child[x][1],mid+1,r);
if(child[x][0])
father[child[x][0]]=x;
if(child[x][1])
father[child[x][1]]=x;
update(x);
}
void Build(int l,int r)
{
int mid=(l+r)>>1;
if(l<mid)
Build(l,mid-1),father[(l+mid-1)>>1]=mid,child[mid][0]=(l+mid-1)>>1;
if(mid<r)
Build(mid+1,r),father[(mid+1+r)>>1]=mid,child[mid][1]=(mid+1+r)>>1;
value[mid]=a[mid],update(mid);
}
void debug()
{
printf("debug begin root=%d\n",root);
for(int i=1;i<=tot;i++)
printf("%d %c %d %d -------%d %d---- %d %d\n",i,char('a'-1+value[i]),value[i],father[i],child[i][0],child[i][1],size[i],w[i]);
}
void rotate(int p)
{
int q=father[p],y=father[q],x=(child[q][1]==p);
father[child[q][x]=child[p][x^1]]=q;
father[child[p][x^1]=q]=p;
father[p]=y;
if(y)
child[y][child[y][1]==q]=p;
update(q);
}
void splay(int x,int aim=0)
{
for(int y;(y=father[x])!=aim;rotate(x))
if(father[y]!=aim)
{
if((child[y][0]==x)==(child[y][0]==y))
rotate(y);
else
rotate(x);
}
if(aim==0)
root=x;
update(x);
}
int select(int x)
{
int t=root;
while(1)
{
if(size[child[t][0]]+1==x)
break;
if(x<=size[child[t][0]])
t=child[t][0];
else
{
x-=size[child[t][0]]+1;
t=child[t][1];
}
}
return t;
}
bool check(int l,int r,int num)
{
// printf("check %d %d %d\n",l,r,num);
if(l+num+1>size[root]||r+num+1>size[root])
return 0;
long long a_l,b_l;
splay(select(l));
splay(select(l+num+1),root);
a_l=w[child[child[root][1]][0]];
//debug();
splay(select(r));
splay(select(r+num+1),root);
b_l=w[child[child[root][1]][0]];
//debug();
//system("pause");
// printf("hash %d %d\n",a_l,b_l);
return a_l==b_l;
}
int main()
{
pow[0]=1;
for(int i=1;i<=MAX;i++)
pow[i]=(pow[i-1]*27)%1000000007;
scanf("%s",s);
len=strlen(s);
a[1]=0;
for(int i=0;i<len;i++)
a[i+2]=int(s[i]-'a'+1);
// for(int i=0;i<=strlen(s);i++) a[i]=i;
a[len+2]=0;
root=tot=0;
build(root,1,len+2);
//debug();
//root=(1+strlen(s)+2)>>1;
//Build(1,strlen(s)+2);
//tot=strlen(s)+2;
int n;
scanf("%d",&n);
// debug();
// system("pause");
/* debug();
for(int i=1;i<=strlen(s)+2;i++)
printf("%d select %d\n",i,select(i));
printf("----------------tot %d\n",tot);*/
while(n--)
{
getchar();
char ch;
scanf("%c",&ch);
if(ch=='Q')
{
int l,r;
scanf("%d%d",&l,&r);
if(l==r)
{
printf("%d\n",tot-l-1);
continue;
}
int L=0,R=tot;
while(L<R)
{
int mid=(L+R)>>1;
if(check(l,r,mid))
L=mid+1;
else
R=mid;
}
printf("%d\n",L-1);
}
if(ch=='R')
{
int x;
char d;
scanf("%d",&x);
getchar();
scanf("%c",&d);
splay(select(x+1));
value[root]=int(d-'a'+1);
//splay(root);
update(root);
}
if(ch=='I')
{
int x;
char d;
scanf("%d",&x);
getchar();
scanf("%c",&d);
splay(select(x+1));
splay(select(x+2),root);
int now=child[root][1];
child[now][0]=++tot;
value[tot]=int(d-'a'+1);
father[child[now][0]]=now;
//splay(tot);
update(tot);
}
}
return 0;
}