标签:
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\n",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 }
Splay维护,询问时二分答案,Hash判定,我用的是53进制。
splay,二分,Hash。
Hash_1014: [JSOI2008]火星人prefix
标签:
原文地址:http://www.cnblogs.com/OYzx/p/5657626.html