去年寒假讲的题···
传送门
因为插入很少所以可以每次暴力重构
查询就用二分+哈希查询
l
c
p
lcp
lcp
好多细节···题目里查询的是原数列的
x
,
y
x,y
x,y坑了不少人
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define maxn 51005
#define LL long long
using namespace std;
int n,m,pos[maxn],pre[maxn],pren;
LL has[maxn],pw[maxn];
char s[maxn];
const int bas=127,mod=1e9+7;
inline void build(int x){
for(int i=x;i<=n;i++)
has[i]=(has[i-1]*bas%mod+s[i])%mod;
}
inline bool check(int len,int x,int y){
LL tmp1=has[x+len-1]-has[x-1]*pw[len]%mod;
LL tmp2=has[y+len-1]-has[y-1]*pw[len]%mod;
tmp1=(tmp1%mod+mod)%mod; tmp2=(tmp2%mod+mod)%mod;
return tmp1==tmp2;
}
inline int query(int x,int y){
int l=0,r=n-max(x,y)+1,res=0;
while(r>=l){
int mid=(l+r)>>1;
if(check(mid,x,y)) res=mid,l=mid+1;
else r=mid-1;
} return res;
}
int main(){
scanf("%s",s+1); n=strlen(s+1); pren=n;
for(int i=1;i<=n;i++) pos[i]=i; pw[0]=1;
for(int i=1;i<=51000;i++) pw[i]=pw[i-1]*bas%mod;
build(1);
scanf("%d",&m);
while(m--){
char ch[5]; scanf("%s",ch);
if(ch[0]=='I'){
scanf("%s",ch); int p; scanf("%d",&p);
p=min(n+1,p); n++;
for(int i=pren;pos[i]>=p;i--) pos[i]++;
for(int i=n;i>=p+1;i--)
s[i]=s[i-1];
s[p]=ch[0]; build(p);
}
else{
int x,y; scanf("%d%d",&x,&y);
int ans=query(pos[x],pos[y]);
printf("%d\n",ans);
}
}
return 0;
}