首页 > 代码库 > bzoj 1014 splay维护hash值

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 }

 

bzoj 1014 splay维护hash值