看了网上的题目关键字(都不用点进去看……我也是醉了)了解到做法= =那就上呗,前面做了好几道Splay的题就是为了练手搞这个的。
Hash判断字符串是否相同应该很好理解吧?>_>我就不细说了
二分这个相同前缀的长度应该也容易>_>
用Splay维护这个Hash值>_>……也挺简单的,跟据size域就能算出以x为根的子树的hash值了。
这次我终于发现了一个之前以为不太重要的点……让我WA了两次= =!!
就是Splay在执行完序列插入的时候,一定要立即Push_up(c[root][1]); Push_up(root);不能想着别的操作随便splay一下自己就维护了……因为size域是会受到影响的!!
1 /************************************************************** 2 Problem: 1014 3 User: Tunix 4 Language: C++ 5 Result: Accepted 6 Time:5600 ms 7 Memory:13288 kb 8 ****************************************************************/ 9 10 //BZOJ 1014 11 #include<vector> 12 #include<cstdio> 13 #include<cstring> 14 #include<cstdlib> 15 #include<iostream> 16 #include<algorithm> 17 #define rep(i,n) for(int i=0;i<n;++i) 18 #define F(i,j,n) for(int i=j;i<=n;++i) 19 #define D(i,j,n) for(int i=j;i>=n;--i) 20 #define pb push_back 21 using namespace std; 22 inline int getint(){ 23 int v=0,sign=1; char ch=getchar(); 24 while(ch<'0'||ch>'9'){ if (ch=='-') sign=-1; ch=getchar();} 25 while(ch>='0'&&ch<='9'){ v=v*10+ch-'0'; ch=getchar();} 26 return v*sign; 27 } 28 const int N=3e5+10,INF=~0u>>2; 29 typedef long long LL; 30 typedef unsigned long long u64; 31 /******************tamplate*********************/ 32 int n,m; 33 char s[N]; 34 int c[N][2],fa[N],size[N],tot,root; 35 u64 sum[N],v[N],mi[N]; 36 #define L c[x][0] 37 #define R c[x][1] 38 void Push_up(int x){ 39 size[x]=size[L]+size[R]+1; 40 sum[x]=sum[L]*mi[size[R]+1]+v[x]*mi[size[R]]+sum[R]; 41 } 42 void Rotate(int x){ 43 int y=fa[x],z=fa[y],l=c[y][1]==x,r=l^1; 44 c[z][c[z][1]==y]=x; 45 fa[x]=z; fa[y]=x; fa[c[x][r]]=y; 46 c[y][l]=c[x][r]; c[x][r]=y; 47 Push_up(y); 48 } 49 void splay(int x,int s=0){ 50 int y; 51 for(;fa[x]!=s;Rotate(x)) 52 if (fa[y=fa[x]]!=s) Rotate(c[y][1]==x^c[fa[y]][1]==y?x:y); 53 Push_up(x); 54 if (!s) root=x; 55 } 56 void New_node(int &x,int f,int key){ 57 x=++tot; 58 fa[x]=f; 59 v[x]=sum[x]=key; L=R=0; 60 size[x]=1; 61 } 62 void Build(int &x,int f,int l,int r){ 63 if (l>r) return; 64 int m=l+r>>1; 65 New_node(x,f,s[m]); 66 Build(L,x,l,m-1); 67 Build(R,x,m+1,r); 68 Push_up(x); 69 } 70 int kth(int x,int k){ 71 if (size[L]+1==k) return x; 72 else if (size[L]>=k) return kth(L,k); 73 else return kth(R,k-size[L]-1); 74 } 75 int query(int x1,int x2){ 76 int l=1,r=min(size[root]-x1,size[root]-x2)-1,mid,ans=0; 77 //由于右侧有一个空白字符,所以要-1 78 u64 n1=0,n2=0; 79 while(l<=r){ 80 mid=l+r>>1; 81 splay(kth(root,x1)); splay(kth(root,x1+mid+1),root); 82 n1=sum[c[c[root][1]][0]]; 83 splay(kth(root,x2)); splay(kth(root,x2+mid+1),root); 84 n2=sum[c[c[root][1]][0]]; 85 if (n1==n2) ans=mid,l=mid+1; 86 else r=mid-1; 87 } 88 return ans; 89 } 90 int main(){ 91 #ifndef ONLINE_JUDGE 92 freopen("1014.in","r",stdin); 93 freopen("1014.out","w",stdout); 94 #endif 95 scanf("%s",s+1); 96 n=strlen(s+1); 97 mi[0]=1; F(i,1,n*3) mi[i]=mi[i-1]*131; 98 s[0]=s[n+1]=0; 99 Build(root,0,0,n+1); 100 m=getint(); 101 char cmd[5],s1[5]; 102 int x,y; 103 F(i,1,m){ 104 scanf("%s",cmd); 105 if (cmd[0]=='Q'){ 106 x=getint(); y=getint(); 107 printf("%d\n",query(x,y)); 108 }else if (cmd[0]=='R'){ 109 x=getint(); scanf("%s",s1); 110 int pos=kth(root,x+1); 111 v[pos]=s1[0]; 112 splay(pos); 113 }else{ 114 x=getint()+1; scanf("%s",s1); 115 splay(kth(root,x)); splay(kth(root,x+1),root); 116 int &pos=c[c[root][1]][0]; 117 New_node(pos,c[root][1],s1[0]); 118 Push_up(c[root][1]); Push_up(root); 119 } 120 } 121 return 0; 122 }