注意到插入次数挺少的,于是每次暴力重构,然后哈希+二分
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #include<cmath> #include<cctype> #include<cstdlib> #include<vector> #include<queue> #include<map> #include<set> #define ll unsigned long long #define R register int using namespace std; namespace Fread { static char B[1<<15],*S=B,*D=B; #define getchar() (S==D&&(D=(S=B)+fread(B,1,1<<15,stdin),S==D)?EOF:*S++) inline int g() { R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-1:fix; do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix; } }using Fread::g; const int N=50210,B=131; int len,m,n,pos[N],x; ll hsh[N],p[N]; char s[N],op[2]; inline void HSH(int st) {for(R i=st;i<=len;++i) hsh[i]=hsh[i-1]*B+s[i]-96;} inline ll calc(int l,int r) {return hsh[r]-hsh[l-1]*p[r-l+1];} inline ll query(int x,int y) { R l=0,r=len-max(x,y)+1; while(l<r) { R md=l+r+1>>1; if(calc(x,x+md-1)==calc(y,y+md-1)) l=md; else r=md-1; } return l; } signed main() { #ifdef JACK freopen("NOIPAK++.in","r",stdin); #endif scanf("%s%d",s+1,&m); len=n=strlen(s+1); HSH(1); for(R i=1;i<=n;++i) pos[i]=i; p[0]=1; for(R i=1;i<=N-10;++i) p[i]=p[i-1]*B; for(R i=1;i<=m;++i) { scanf("%s",op); if(op[0]=='I') { scanf("%s%d",op,&x); if(x>len) x=len+1; memcpy(s+x+1,s+x,sizeof(char)*(len-x+1)); s[x]=op[0]; for(R j=n;j>=1;--j) { if(pos[j]<x) break; ++pos[j]; } ++len; HSH(x); } else { R x,y; scanf("%d%d",&x,&y); printf("%d\n",query(pos[x],pos[y])); } } }
2019.06.10