Hash_1014: [JSOI2008]火星人prefix

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <algorithm>
 6 using namespace std;
 7 typedef unsigned int ll;
 8 #define maxn 150005
 9 #define p 53
10 int n,m,root,tot,fa[maxn],son[maxn][2],size[maxn];
11 ll val[maxn],sum[maxn],bin[maxn];
12 char st[maxn],op[5];
13 void read(int &x){
14     x=0; int f=1; char ch;
15     for (ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') f=-1;
16     for (;isdigit(ch);ch=getchar()) x=x*10+ch-'0'; x*=f;
17 }
18 struct SPLAY{
19     int which(int x){
20         return son[fa[x]][1]==x;
21     }
22     void updata(int x){
23         int ls=son[x][0],rs=son[x][1];
24         size[x]=size[ls]+size[rs]+1;
25         sum[x]=sum[rs]+val[x]*bin[size[rs]]+sum[ls]*bin[1+size[rs]];
26     }
27     int build(int l,int r){
28         int x; if (l>r) return 0; int mid=(l+r)>>1;    
29         if (mid==0) x=n+1,val[x]=0;
30         else if (mid==n+1) x=n+2,val[x]=0;
31         else x=mid,val[x]=st[x]-'a'; size[x]=1;
32         son[x][0]=build(l,mid-1),son[x][1]=build(mid+1,r),updata(x);
33         if (son[x][0]) fa[son[x][0]]=x;
34         if (son[x][1]) fa[son[x][1]]=x;
35         return x; 
36     }
37     void rotata(int x){
38         int y=fa[x],d=which(x),dd=which(y);
39         if (fa[y]) son[fa[y]][dd]=x; fa[x]=fa[y];
40         fa[son[x][d^1]]=y,son[y][d]=son[x][d^1];
41         fa[y]=x,son[x][d^1]=y,updata(y);
42     }
43     void splay(int x,int goal){
44         while (fa[x]!=goal){
45             if (fa[fa[x]]==goal) rotata(x);
46             else if (which(x)==which(fa[x])) rotata(fa[x]),rotata(x);
47             else rotata(x),rotata(x);
48         }
49         if (goal==0) root=x; updata(x);
50     }
51     int kth(int x){
52         int y=root,ls,rs; if (!root) return 0;
53         for (;;){
54             ls=son[y][0],rs=son[y][1];
55             if (size[ls]+1==x) return y;
56             else if (size[ls]>=x) y=ls;
57             else x-=size[ls]+1,y=rs;
58         }
59     }
60     bool check(int x,int y,int len){
61         int t1,t2; t1=kth(x),t2=kth(x+len+1);
62         ll z;splay(t1,0),splay(t2,t1),z=sum[son[t2][0]];
63         t1=kth(y),t2=kth(y+len+1); splay(t1,0),splay(t2,t1);
64         return z==sum[son[t2][0]];
65     }
66 }Splay;
67 void query(int x,int y){
68     int l=1,r,mid,ans=0; r=min(tot-2-x+1,tot-2-y+1);
69     while (l<=r){
70         mid=(l+r)>>1;
71         if (Splay.check(x,y,mid)==1) ans=mid,l=mid+1;
72         else r=mid-1;
73     }printf("%d
",ans);
74 }
75 int main(){
76     bin[0]=1; for (int i=1;i<=150000;i++) bin[i]=bin[i-1]*p;
77     scanf("%s",st+1),n=strlen(st+1);
78     root=Splay.build(0,n+1); tot=n+2;
79     read(m);
80     for (int x,y;m;m--){
81         scanf("%s",op+1);
82         if (op[1]=='Q') read(x),read(y),query(x,y);
83         else if (op[1]=='R') read(x),scanf("%s",op+1),x=Splay.kth(x+1),Splay.splay(x,0),val[x]=op[1]-'a',Splay.updata(x);
84         else{
85             read(x),scanf("%s",op+1),++tot,val[tot]=op[1]-'a',size[tot]=1;
86             int t1=Splay.kth(x+1),t2=Splay.kth(x+2); Splay.splay(t1,0),Splay.splay(t2,t1);
87             fa[tot]=t2,son[t2][0]=tot,Splay.updata(t2),Splay.splay(tot,0);
88         }
89     }
90     return 0;
91 }
View Code

Splay维护,询问时二分答案,Hash判定,我用的是53进制。

splay,二分,Hash。

原文地址:https://www.cnblogs.com/OYzx/p/5657626.html