bzoj 1014 splay维护hash值
被后缀三人组虐了一下午,写道水题愉悦身心。
题很裸,求lcq时二分下答案就行了,写的不优美会被卡时。
(写题时精神恍惚,不知不觉写了快两百行。。。竟然调都没调就A了。。。我还是继续看后缀自动机吧。。。)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #define bas 131 6 #define p 1000000007 7 #define N 100005 8 #define ll long long 9 using namespace std; 10 char c[100005]; 11 int n; 12 int cnt,root; 13 int ch[N][2],fa[N],size[N]; 14 ll pow[N],k[N]; 15 ll zi[N]; 16 ll sum[N]; 17 void push_up(int x) 18 { 19 size[x]=size[ch[x][0]]+size[ch[x][1]]+1; 20 k[x]=k[ch[x][1]]+zi[x]*pow[size[ch[x][1]]]+k[ch[x][0]]*pow[size[ch[x][1]]+1]; 21 k[x]%=p; 22 } 23 void rotate(int pp) 24 { 25 int q=fa[pp],y=fa[q],x=(ch[q][1]==pp); 26 ch[q][x]=ch[pp][x^1];fa[ch[q][x]]=q; 27 ch[pp][x^1]=q;fa[q]=pp; 28 fa[pp]=y; 29 if(y) 30 { 31 if(ch[y][0]==q)ch[y][0]=pp; 32 else ch[y][1]=pp; 33 } 34 push_up(q); 35 } 36 void splay(int x) 37 { 38 for(int y;y=fa[x];rotate(x)) 39 { 40 if(fa[y]) 41 { 42 if((ch[fa[y]][0]==y&&ch[y][0]==x)||(ch[fa[y]][1]==y&&ch[y][1]==x))rotate(y); 43 else rotate(x); 44 } 45 } 46 push_up(x); 47 root=x; 48 } 49 int find(int x,int kk) 50 { 51 if(size[ch[x][0]]+1==kk)return x; 52 if(size[ch[x][0]]+1>=kk)return find(ch[x][0],kk); 53 return find(ch[x][1],kk-size[ch[x][0]]-1); 54 } 55 ll pp(int x,int l) 56 { 57 int r=l+x-1; 58 if(l!=1) 59 { 60 int y=find(root,l-1); 61 splay(y); 62 if(r==size[root]) 63 { 64 return k[ch[y][1]]; 65 } 66 else 67 { 68 fa[ch[y][1]]=0; 69 int z=find(root,r+1); 70 splay(z); 71 fa[z]=y;root=y;ch[y][1]=z; 72 return k[ch[z][0]]; 73 } 74 } 75 else 76 { 77 if(r==size[root])return k[root]; 78 splay(find(root,r+1)); 79 return k[ch[root][0]]; 80 } 81 } 82 bool pan(int x,int l,int r) 83 { 84 if(!x)return 1; 85 ll t1=pp(x,l),t2=pp(x,r); 86 if(t1==t2)return 1; 87 return 0; 88 } 89 int main() 90 { 91 scanf("%s",c); 92 n=strlen(c);pow[0]=1; 93 for(int i=1;i<=100000;i++)pow[i]=(pow[i-1]*bas)%p; 94 for(int i=0;i<n;i++) 95 { 96 sum[i+1]=sum[i]*bas+c[i]-'a'+1; 97 sum[i+1]%=p; 98 } 99 root=1;cnt=1;k[1]=sum[n];size[1]=n;zi[1]=c[n-1]-'a'+1; 100 for(int i=n-1;i>=1;i--) 101 { 102 cnt++;fa[cnt]=cnt-1; 103 ch[cnt-1][0]=cnt; 104 k[cnt]=sum[i]; 105 size[cnt]=i; 106 zi[cnt]=c[i-1]-'a'+1; 107 } 108 splay(cnt); 109 int m; 110 scanf("%d",&m); 111 char t[2];int t1,t2; 112 while(m--) 113 { 114 scanf("%s",t); 115 if(t[0]=='I') 116 { 117 scanf("%d",&t1);scanf("%s",t); 118 if(t1!=0) 119 { 120 int y=find(root,t1); 121 splay(y); 122 if(ch[y][1]!=0) 123 { 124 int tmp=ch[y][1]; 125 while(ch[tmp][0])tmp=ch[tmp][0]; 126 fa[ch[y][1]]=0; 127 splay(tmp); 128 root=y; 129 ch[y][1]=tmp; 130 fa[tmp]=y; 131 ch[tmp][0]=++cnt; 132 fa[cnt]=tmp; 133 k[cnt]=t[0]-'a'+1; 134 zi[cnt]=t[0]-'a'+1; 135 size[cnt]=1; 136 push_up(tmp); 137 } 138 else 139 { 140 ch[y][1]=++cnt; 141 fa[cnt]=y; 142 k[cnt]=t[0]-'a'+1; 143 zi[cnt]=t[0]-'a'+1; 144 size[cnt]=1; 145 } 146 push_up(y); 147 } 148 else 149 { 150 int y=find(root,1); 151 splay(y); 152 ch[y][0]=++cnt; 153 fa[cnt]=y; 154 k[cnt]=t[0]-'a'+1; 155 zi[cnt]=t[0]-'a'+1; 156 size[cnt]=1; 157 push_up(y); 158 } 159 } 160 else if(t[0]=='Q') 161 { 162 scanf("%d%d",&t1,&t2);if(t1>t2)swap(t1,t2); 163 int l=0;int r=size[root]-t2+1; 164 while(l<=r) 165 { 166 int mid=(l+r)>>1; 167 if(pan(mid,t1,t2))l=mid+1; 168 else r=mid-1; 169 } 170 printf("%d\n",r); 171 } 172 else 173 { 174 scanf("%d",&t1);scanf("%s",t); 175 int y=find(root,t1); 176 splay(y); 177 k[y]-=zi[y]*pow[size[ch[y][1]]]; 178 k[y]+=(t[0]-'a'+1)*pow[size[ch[y][1]]]; 179 k[y]=((k[y]%p)+p)%p; 180 zi[y]=t[0]-'a'+1; 181 } 182 } 183 return 0; 184 }