题干:给你一段区间,并给你m个操作,操作包含:
1.计算以两点为起点的最长相同串长度。
2.将某字符改为另一字符。
3.在某位置后加入另一字符。
splay的题,还要配上hash,套上log级的验证,时间O(n*log^2);
代码:
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define N 100500 #define seed 2333 #define ull unsigned long long char ch[N],c[2]; int n,m,rt,tot,a[N]; ull mi[2*N]; struct Splay { int ch[2],fa,vl,siz; ull hs; }tr[N]; void update(int u) { int l = tr[u].ch[0],r = tr[u].ch[1]; tr[u].siz = tr[l].siz+tr[r].siz+1; tr[u].hs = tr[l].hs*mi[tr[r].siz+1]+tr[u].vl*mi[tr[r].siz]+tr[r].hs; } void rotate(int x) { int y = tr[x].fa,z = tr[y].fa,k=(tr[y].ch[1]==x); tr[y].ch[k]=tr[x].ch[k^1];tr[tr[x].ch[k^1]].fa=y; tr[x].ch[k^1]=y;tr[y].fa=x; tr[z].ch[tr[z].ch[1]==y]=x;tr[x].fa=z; update(y);update(x); } void splay(int x,int goal) { while(tr[x].fa!=goal) { int y = tr[x].fa,z = tr[y].fa; if(z!=goal) ((tr[y].ch[1]==x)^(tr[z].ch[1]==y))?rotate(x):rotate(y); rotate(x); } if(!goal)rt=x; } void build(int l,int r,int f) { if(l>r)return ; int mid = (l+r)>>1; if(l==r) { tr[mid].hs = a[l]; }else { build(l,mid-1,mid); build(mid+1,r,mid); } tr[mid].vl = a[mid]; tr[mid].fa = f; tr[f].ch[mid>=f]=mid; update(mid); } int find(int x,int k) { int t = tr[tr[x].ch[0]].siz; if(t>=k)return find(tr[x].ch[0],k); else if(k==t+1)return x; else return find(tr[x].ch[1],k-1-t); } int deal(int x,int y) { x = find(rt,x),y = find(rt,y); splay(x,0);splay(y,x); return tr[y].ch[0]; } ull query(int x,int y) { x = deal(x,y+1); return tr[x].hs; } int get(int x,int y) { int ans = 0; for(int i=20;i>=0;i--) { if(y+(1<<i)>n+1||x+(1<<i)>n+1)continue; if(query(x,x+(1<<i))==query(y,y+(1<<i))) x+=(1<<i),y+=(1<<i),ans|=(1<<i); } return ans; } void cg(int x,int k) { x = find(rt,x); splay(x,0); tr[x].vl = k; update(x); } void insert(int x,int k) { int l = find(rt,x),r = find(rt,x+1); splay(l,0);splay(r,l); tot++; tr[tot].vl = tr[tot].hs = k; tr[tot].fa = r; tr[r].ch[0]= tot; tr[tot].siz=1; update(r); update(rt); } int main() { scanf("%s%d",ch+1,&m); n = strlen(ch+1); mi[0]=1; for(int i=1;i<=200000;i++)mi[i]=mi[i-1]*seed; for(int i=1;i<=n;i++)a[i+1]=ch[i]-'a'+1; build(1,n+2,0); rt=(3+n)>>1; tot = n+2; int x,y; for(int i=1;i<=m;i++) { scanf("%s%d",c,&x); if(c[0]=='Q') { scanf("%d",&y); printf("%d ",get(x,y)); }else if(c[0]=='R') { scanf("%s",c); cg(x+1,c[0]-'a'+1); }else { scanf("%s",c); n++; insert(x+1,c[0]-'a'+1); } } return 0; }