zoukankan      html  css  js  c++  java
  • 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
    ";
    #else
        const char LL[]="%lld
    ";
    #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
    ",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;
    }
  • 相关阅读:
    关于重复记录
    easyui-dataGrid
    初尝easyui
    字符串处理の合并记录行
    实现P2P远程控制项目的基本逻辑
    命令行启动vscode中的ssh-remote插件并指定路径
    关于TCP三次握手的意义及其具体实现解释
    Git使用建议及规范
    MySQL C API的参数化查询
    gdb定位程序CPU占用过高问题
  • 原文地址:https://www.cnblogs.com/Gloid/p/10281592.html
Copyright © 2011-2022 走看看