bzoj1014 神奇的平衡树+hash

来源:互联网 发布:色内内电影网新域名 编辑:程序博客网 时间:2024/05/16 17:32

哇塞学到了用平衡树存hash值,黄学长的模板用起来就是好耍。
这道题如果没有修改操作的话,二分hash值就可以搞定或者后缀数组什么的,但这道题要修改所以就用平衡树来存hash值就好了,写起来并不难。。

#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>#define N 150005#define mod 9875321#define ll long longusing namespace std;int c[N][2],siz[N],sz,fa[N],id[N],v[N],h[N],p[N],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[N],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);        }    }}
原创粉丝点击