看了网上的题目关键字(都不用点进去看……我也是醉了)了解到做法= =那就上呗,前面做了好几道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 }
View Code

相关文章: