bzoj 1014:[JSOI2008]火星人prefix splay维护hash 二分求lcp
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; #define N 220000 int ch[N][2],pre[N],s[N],val[N],b[N],root,tot,siz[N]; char a[N]; int ff[N]; void up(int x){ siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1; s[x]=(s[ch[x][0]]*27+val[x])*ff[siz[ch[x][1]]]+s[ch[x][1]]; } void rot(int x){ int y=pre[x],z=pre[y],k=ch[y][0]==x; pre[ch[y][!k]=ch[x][k]]=y; pre[ch[x][k]=y]=x; pre[x]=z; if(z)ch[z][ch[z][1]==y]=x; else root=x; up(y); } void splay(int x,int f){ int y,z; for(;pre[x]!=f;){ y=pre[x],z=pre[y]; if(z==f)rot(x); else if((ch[y][1]==x)==(ch[z][1]==y))rot(y),rot(x); else rot(x),rot(x); } up(x); } void select(int k,int f){ int x=root; while(siz[ch[x][0]]+1!=k){ if(siz[ch[x][0]]>=k)x=ch[x][0]; else k-=siz[ch[x][0]]+1,x=ch[x][1]; } splay(x,f); } int build(int l,int r,int p){ if(l>r)return 0; int k=++tot; int mid=(l+r)>>1; pre[k]=p; val[k]=b[mid]; ch[k][0]=build(l,mid-1,k); ch[k][1]=build(mid+1,r,k); up(k); return k; } void add(int x,int y){ select(x+1,0); select(x+2,root); ch[ch[root][1]][0]=++tot; siz[tot]=1; pre[tot]=ch[root][1]; val[tot]=s[tot]=y; splay(tot,0); } void change(int x,int y){ select(x,0); select(x+2,root); int k=ch[ch[root][1]][0]; s[k]=val[k]=y; splay(k,0); } bool deng(int x,int y,int k){ select(x,0); select(x+k+1,root); int a1,a2; a1=s[ch[ch[root][1]][0]]; select(y,0); select(y+k+1,root); a2=s[ch[ch[root][1]][0]]; return a1==a2; } int lcp(int x,int y){ int le=0; int ri=min(tot-x,tot-y),mid; while(le+1!=ri){ mid=(le+ri)>>1; if(deng(x,y,mid))le=mid; else ri=mid; } return le; } int main(){ ff[0]=1; for(int i=1;i<=100100;i++)ff[i]=ff[i-1]*27; scanf("%s",a); int t=strlen(a); for(int i=0;i<t;i++)b[i+1]=a[i]-'a'+1; int m; tot=2; root=1; ch[1][1]=2; pre[2]=1; ch[2][0]=build(1,t,2); up(2); up(1); scanf("%d",&m); for(int i=1;i<=m;i++){ char a,b; int c,d; scanf(" %c",&a); if(a=='Q'){ scanf("%d%d",&c,&d); printf("%d\n",lcp(c,d)); } if(a=='I'){ scanf("%d %c",&c,&b); add(c,b-'a'+1); } if(a=='R'){ scanf("%d %c",&c,&b); change(c,b-'a'+1); } } }