bzoj1014 神奇的平衡树+hash
2017-08-12 21:28
211 查看
哇塞学到了用平衡树存hash值,黄学长的模板用起来就是好耍。
这道题如果没有修改操作的话,二分hash值就可以搞定或者后缀数组什么的,但这道题要修改所以就用平衡树来存hash值就好了,写起来并不难。。
这道题如果没有修改操作的话,二分hash值就可以搞定或者后缀数组什么的,但这道题要修改所以就用平衡树来存hash值就好了,写起来并不难。。
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #define N 150005 #define mod 9875321 #define ll long long using namespace std; int c [2],siz ,sz,fa ,id ,v ,h ,p ,n,rt,m,a,b; void update(int x){ int l=c[x][0],r=c[x][1]; siz[x]=siz[l]+siz[r]+1; h[x]=h[l]+(ll)p[siz[l]]*v[x]%mod+(ll)p[siz[l]+1]*h[r]%mod; h[x]%=mod; } void rotate(int x,int &k){ int y=fa[x],z=fa[y],l,r; if(c[y][0]==x)l=0;else l=1;r=l^1; if(y==k)k=x; else c[z][c[z][1]==y]=x; fa[x]=z;fa[y]=x;fa[c[x][r]]=y; c[y][l]=c[x][r];c[x][r]=y; update(y);update(x); } void splay(int x,int &k){ while(x!=k){ int y=fa[x],z=fa[y]; if(y!=k){ if(c[y][0]==x^c[z][0]==y) rotate(x,k); else rotate(y,k); } rotate(x,k); } } int find(int x,int rk){ int l=c[x][0],r=c[x][1]; if(siz[l]+1==rk) return x; else if(siz[l]>=rk) return find(l,rk); else return find(r,rk-siz[l]-1); } char ch ,s[2],d[2]; void insert(int k,int val){ int x=find(rt,k+1),y=find(rt,k+2); splay(x,rt);splay(y,c[x][1]); int z=++sz;c[y][0]=z; v[z]=h[z]=val;fa[z]=y; update(z);update(y);update(x); } int query(int k,int mid){ int x=find(rt,k),y=find(rt,k+mid+1); splay(x,rt);splay(y,c[x][1]); int z=c[y][0]; return h[z]; } void solv(int x,int y) { int l=1,r=min(sz-x,sz-y)-1,ans=0; while(l<=r) { int mid=(l+r)>>1; if(query(x,mid)==query(y,mid))l=mid+1,ans=mid; else r=mid-1; } printf("%d\n",ans); } void build(int l,int r,int f){ if(l>r)return; int now=id[l],last=id[f]; if(l==r){ v[now]=h[now]=ch[l]-'a'+1; fa[now]=last;siz[now]=1; c[last][l>=f]=now; return; } int mid=(l+r)>>1;now=id[mid]; build(l,mid-1,mid);build(mid+1,r,mid); v[now]=ch[mid]-'a'+1;fa[now]=last;update(now); c[last][mid>=f]=now; } int main(){ scanf("%s",ch+2);p[0]=1; n=strlen(ch+2); for(int i=1;i<=n+2;i++)id[i]=i; for(int i=1;i<N;i++) p[i]=p[i-1]*27%mod; build(1,n+2,0);sz=n+2;rt=(n+3)>>1; scanf("%d",&m); for(int i=1;i<=m;i++){ scanf("%s",s); if(s[0]=='Q'){ scanf("%d%d",&a,&b); solv(a,b); } if(s[0]=='R'){ scanf("%d%s",&a,d); int x=find(rt,a+1);splay(x,rt); v[x]=d[0]-'a'+1;update(x); } if(s[0]=='I'){ scanf("%d%s",&a,d); insert(a,d[0]-'a'+1); } } }
相关文章推荐
- 【平衡树维护序列+Hash求LCP】BZOJ1014(JSOI2008)[火星人prefix]题解
- 【BZOJ1014】【JSOI2008】火星人prefix Splay处理区间,hash+dichotomy(二分)check出解
- BZOJ 1014 JSOI2008 火星人prefix Splay+Hash+二分
- [BZOJ1014][JSOI2008]火星人prefix splay+二分+hash
- 【bzoj1014】[JSOI2008]火星人prefix splay+hash+二分
- 【bzoj1014】【jsoi2008】【火星人prefix】【splay+hash】
- BZOJ 1014: [JSOI2008]火星人prefix [splay 二分+hash] 【未完】
- 【BZOJ1014】[JSOI2008]火星人prefix【Splay】【Hash】
- BZOJ1014 [JSOI2008]火星人prefix(Splay+字符串Hash)
- 【BZOJ1014】火星人prefix(splay,Hash)
- bzoj1014 [JSOI2008]火星人prefix ( splay + hash )
- [BZOJ1014]JSOI2008 火星人|splay|hash
- [BZOJ 1014] [JSOI2008] 火星人prefix 【Splay + Hash】
- bzoj 1014 LCP 二分 Hash 匹配
- BZOJ 1014 火星人 prefix (splay hash 二分答案)
- BZOJ 1014 JSOI 2008 火星人prefix Splay维护字符串Hash + 二分
- 【BZOJ】1014: [JSOI2008]火星人prefix(splay+hash+二分+lcp)
- 【BZOJ1014】火星人prefix Splay 字符串Hash
- bzoj1014: [JSOI2008]火星人prefix splay+hash
- BZOJ 1014: [JSOI2008]火星人prefix( splay + hash )