• bzoj千题计划285:bzoj2555: SubString


    http://www.lydsy.com/JudgeOnline/problem.php?id=2555

    后缀自动机,用LCT维护parent树

    一个串的出现次数 = parent 树 上 其所在状态 的 子树 叶节点 | Right | 之和

    若在parent中np的子节点中加一个节点p,设p的 | Right | = sum,那么 根节点到np 的整条链上的所有状态的 | Right | 都要 + sum

    若更换掉q原来的父节点, 设q的 | Right | = sum,那么 根节点到q 的整条链上的所有状态的 | Right | 都要 -  sum

    注意  decodeWithMask mask的修改 不影响全局的mask,全局的mask 只 会受 last_ans的影响  

    三个 无脑shabi错误的血泪史:

     

    #include<cstdio>
    #include<cstring>
    #include<iostream>
       
    using namespace std;
       
    #define N 600002
       
    char s[3000001];
       
    int tot=1,fa[N<<1],len[N<<1],ch[N<<1][26];
    int p,q,np,nq,last=1;
       
    int mask;
    string chars;
       
    int sum[N<<1],tag[N<<1];
    int Sfa[N<<1],Sch[N<<1][2];
       
    int st[N<<1],top;
       
    void decodeWithMask(int mask)
    {
        scanf("%s",s);
        chars=s;
        int n=chars.length();
        for (int j=0;j<n;j++) 
        {
            mask=(mask*131+j)%n;
            char t=chars[j];
            chars[j]=chars[mask];
            chars[mask]=t;
        }
    }
       
    bool isroot(int x)
    {
        return Sch[Sfa[x]][0]!=x && Sch[Sfa[x]][1]!=x;
    }
       
    bool getson(int x)
    {
        return Sch[Sfa[x]][1]==x;
    }
       
    void tagging(int x,int y)
    {
        sum[x]+=y; tag[x]+=y;
    }
       
    void down(int x)
    {
        if(!tag[x]) return;
        if(Sch[x][0]) tagging(Sch[x][0],tag[x]);
        if(Sch[x][1]) tagging(Sch[x][1],tag[x]);
        tag[x]=0;
    }
       
    void rotate(int x)
    {
        int y=Sfa[x],z=Sfa[y]; int k=getson(x);
        if(!isroot(y)) Sch[z][Sch[z][1]==y]=x;
        Sch[y][k]=Sch[x][k^1]; Sch[x][k^1]=y;
        Sfa[x]=z; Sfa[y]=x; Sfa[Sch[y][k]]=y;
    }
       
    void splay(int x)
    {
        st[top=1]=x;
        for(int i=x;!isroot(i);i=Sfa[i]) st[++top]=Sfa[i];
        for(int i=top;i;--i) down(st[i]);
        int y;
        while(!isroot(x))
        {
            y=Sfa[x];
            if(!isroot(y)) rotate(getson(y)==getson(x) ? y : x);
            rotate(x);
        }
    }
       
    void access(int x)
    {
        int t=0;
        while(x)
        {
            splay(x);
            Sch[x][1]=t;
            t=x; x=Sfa[x];
        }
    }
       
    void link(int x,int f)
    {
        Sfa[x]=f;
        access(f);
        splay(f);
        tagging(f,sum[x]);
    }
       
    void cut(int x)
    {
        access(x);
        splay(x);
        tagging(Sch[x][0],-sum[x]);
        Sfa[Sch[x][0]]=0;
        Sch[x][0]=0;
    }
       
    void extend(int c)
    {
        len[np=++tot]=len[last]+1;
        sum[np]++;
        for(p=last;p && !ch[p][c]; p=fa[p]) ch[p][c]=np;
        if(!p) fa[np]=1,link(np,1);
        else
        {
            q=ch[p][c];
            if(len[q]==len[p]+1) fa[np]=q,link(np,q);
            else
            {
                len[nq=++tot]=len[p]+1;
                memcpy(ch[nq],ch[q],sizeof(ch[nq]));
                fa[nq]=fa[q]; link(nq,fa[q]);
                fa[q]=fa[np]=nq;
                cut(q); link(q,nq); link(np,nq);
                for(;ch[p][c]==q;p=fa[p]) ch[p][c]=nq;
            }
        }
        last=np;
    }
       
    void build()
    {
        scanf("%s",s+1);
        int n=strlen(s+1);
        for(int i=1;i<=n;++i) extend(s[i]-'A');
    }
       
    void add()
    {
        decodeWithMask(mask);
        int n=chars.length();
        for(int i=0;i<n;++i) extend(chars[i]-'A');
    }
       
    int query()
    {
        decodeWithMask(mask);
        int n=chars.length();
        int now=1;
        for(int i=0;i<n;++i)
            if(!(now=ch[now][chars[i]-'A'])) return 0;
        splay(now);
        return sum[now];
    }
       
    int main()
    {
        int T,ans;
        scanf("%d",&T);
        build();
        while(T--)
        {
            scanf("%s",s);
            if(s[0]=='A') add();
            else
            {
                ans=query();
                printf("%d
    ",ans);
                mask^=ans;
            }
        }
    }
  • 相关阅读:
    SpringBoot框架中,使用过滤器进行加密解密操作(一)
    Oracle SQL Developer 连接数据库问题总结
    ios 自动布局
    iOS 跳转动画 改变pushViewController动画
    ios修饰符
    iOS 屏幕弹框
    iOS 单例类,
    Swift 阳历转农历,农历转公历
    Swift限制只能输入中文(粘贴无效),Swift限制输入字数
    swift判断 UILabel文字是否被折叠 是否有省略号 是否没显示全
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/8576812.html
Copyright © 2020-2023  润新知