标签:
Splay维护Hash值,每次二分。
#include<bits/stdc++.h> #define L(t) (t)->c[0] #define R(t) (t)->c[1] #define Z(t) (L(t)->s+1) #define N 100010 #define M (l+r>>1) typedef unsigned long long ull; ull a[N]; struct node{ int v,s; ull u; node* c[2]; node(int v,node* x,node* y) :v(v),s(0),u(v){ c[0]=x,c[1]=y; } }*null=new node(0,0,0),*root; node* update(node* t){ t->s=R(t)->s+Z(t); t->u=L(t)->u+t->v *a[L(t)->s]+R(t)->u*a[Z(t)]; return t; } void link(bool i,node*& t,node*& s){ node* d=t->c[i]; t->c[i]=s; s=update(t); t=d; } node* splay(int v,node*& t=root){ node* d[]={null,null}; while(v!=Z(t)){ bool i=v>Z(t); v-=i*Z(t); if(v!=Z(t->c[i]) &&i==v>Z(t->c[i])){ v-=i*Z(t->c[i]); link(i,t,t->c[i]->c[i^1]); } link(i,t,d[i]); } for(int i=0;i!=2;++i){ node* s=t->c[i^1]; while(d[i]!=null) link(i,d[i],s); t->c[i^1]=s; } return update(t); } node* build(char* v,int l,int r){ return l>r?null :update(new node(v[M], build(v,l,M-1), build(v,M+1,r))); } node*& interval(int l,int r){ splay(l); splay(r-l+2,R(root)); return L(R(root)); } int n; bool check(int v,int x,int y){ ull u=interval(x,x+v-1)->u; return u==interval(y,y+v-1)->u; } char v[N]; int main(){ a[0]=1; for(int i=1;i!=N;++i) a[i]=a[i-1]*23; int m,x,y; char s[2],d[2]; scanf("%s%d",v+1,&m); n=strlen(v+1); root=build(v,0,n+1); while(m--){ scanf("%s%d",s,&x); if(*s==‘Q‘){ scanf("%d",&y); int l=0,r=n-std::max(x,y)+1; while(l!=r){ int mid=l+r+1>>1; if(check(mid,x,y)) l=mid; else r=mid-1; } printf("%d\n",l); } if(*s==‘R‘){ scanf("%s",d); splay(x+1)->v=*d; } if(*s==‘I‘&&++n){ scanf("%s",d); interval(x+1,x)=update( new node(*d,null,null)); } } }
bzoj1014: [JSOI2008]火星人prefix Hash+Splay
标签:
原文地址:http://www.cnblogs.com/f321dd/p/5495901.html