BZOJ1014 JSOI2008火星人(splay+哈希)

  splay维护哈希值即可。

#include<iostream> 
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define ull unsigned long long
#define N 100010
#define P 509
#define lson tree[k].ch[0]
#define rson tree[k].ch[1]
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{
    int x=0,f=1;char c=getchar();
    while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
    while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    return x*f;
}
int m,cnt,root;
ull p[N];
char s[N];
struct data{int ch[2],fa,size,x;ull hash;
}tree[N];
void up(int k)
{
    tree[k].size=tree[lson].size+tree[rson].size+1;
    tree[k].hash=tree[lson].hash*p[tree[rson].size+1]+tree[k].x*p[tree[rson].size]+tree[rson].hash;
}
void build(int &k,int l,int r)
{
    if (l>r) return;
    int mid=l+r>>1;
    k=++cnt,tree[k].x=s[mid]-'a';
    build(lson,l,mid-1),build(rson,mid+1,r);
    tree[lson].fa=tree[rson].fa=k;
    up(k);
}
int whichson(int k){return tree[tree[k].fa].ch[1]==k;}
void move(int k)
{
    int fa=tree[k].fa,gf=tree[fa].fa,p=whichson(k);
    if (fa) tree[gf].ch[whichson(fa)]=k;tree[k].fa=gf;
    tree[tree[k].ch[!p]].fa=fa,tree[fa].ch[p]=tree[k].ch[!p];
    tree[k].ch[!p]=fa,tree[fa].fa=k;
    up(fa),up(k);
}
void splay(int k,int rt)
{
    while (tree[k].fa!=rt)
    {
        int fa=tree[k].fa;
        if (tree[fa].fa!=rt)
            if (whichson(k)^whichson(fa)) move(k);
            else move(fa);
        move(k);
    }
    if (!rt) root=k;
}
int find(int k,int x)
{
    if (tree[lson].size+1==x) return k;
    if (tree[lson].size>=x) return find(lson,x);
    else return find(rson,x-tree[lson].size-1);
}
int split(int x,int y)
{
    int p=find(root,x),q=find(root,y+2);
    splay(p,0);
    splay(q,p);
    return q;
}
ull gethash(int x,int y)
{
    int p=split(x,y);
    return tree[tree[p].ch[0]].hash;
}
void ins(int k,int x)
{
    int p=split(k+1,k);
    k=++cnt;tree[k].fa=p,tree[p].ch[0]=k,tree[k].x=x;
    up(k),up(p),up(root);
}
void modify(int k,int x)
{
    int p=split(k,k);
    tree[k=tree[p].ch[0]].x=x;
    up(k),up(p),up(root);
}
int main()
{
#ifndef ONLINE_JUDGE
    freopen("bzoj1014.in","r",stdin);
    freopen("bzoj1014.out","w",stdout);
    const char LL[]="%I64d\n";
#else
    const char LL[]="%lld\n";
#endif
    scanf("%s",s+1);int n=strlen(s+1);
    p[0]=1;for (int i=1;i<=100000;i++) p[i]=p[i-1]*P;
    build(root,0,n+1);
    m=read();
    while (m--)
    {
        char c=getc();
        if (c=='Q')
        {
            int x=read(),y=read();
            int l=1,r=n-max(x,y)+1,ans=0;
            while (l<=r)
            {
                int mid=l+r>>1;
                if (gethash(x,x+mid-1)==gethash(y,y+mid-1)) ans=mid,l=mid+1;
                else r=mid-1;
            }
            printf("%d\n",ans);
        }
        if (c=='I')
        {
            n++;int x=read();char c=getc();
            ins(x,c-'a');
        }
        if (c=='R')
        {
            int x=read();char c=getc();
            modify(x,c-'a');
        }
    }
    return 0;
}

 

posted @ 2019-01-17 12:27  Gloid  阅读(129)  评论(0编辑  收藏  举报