[BZOJ2555] SubString

Posted 租酥雨

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[BZOJ2555] SubString相关的知识,希望对你有一定的参考价值。

bzoj

题意

给你一个初始模板串,要求资瓷以下两个操作:
1、在模板串的末尾接上一个串;
2、查询一个串在模板串中出现了多少次。
强制在线。

sol

末尾添加直接\(extend\)
查询一个串的出现次数就是查对应状态的\(right\)集合大小。
由于是动态的所以需要用\(LCT\)维护。相当于是在维护子树信息(子树和)。

code

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 1250000;
struct lct{
    int fa[N],ch[2][N],val[N],sum[N];
    bool son(int x)
        {
            return x==ch[1][fa[x]];
        }
    bool isroot(int x)
        {
            return x!=ch[0][fa[x]]&&x!=ch[1][fa[x]];
        }
    void pushup(int x)
        {
            sum[x]=val[x]+sum[ch[0][x]]+sum[ch[1][x]];
        }
    void rotate(int x)
        {
            int y=fa[x],z=fa[y],c=son(x);
            ch[c][y]=ch[c^1][x];if (ch[c][y]) fa[ch[c][y]]=y;
            fa[x]=z;if (!isroot(y)) ch[son(y)][z]=x;
            ch[c^1][x]=y;fa[y]=x;pushup(y);
        }
    void splay(int x)
        {
            for (int y=fa[x];!isroot(x);rotate(x),y=fa[x])
                if (!isroot(y)) son(x)^son(y)?rotate(x):rotate(y);
            pushup(x);
        }
    void access(int x)
        {
            for (int y=0;x;y=x,x=fa[x])
            {
                splay(x);val[x]+=sum[ch[1][x]]-sum[y];
                ch[1][x]=y;pushup(x);
            }
        }
    void link(int x,int y)
        {
            splay(x);access(y);splay(y);
            fa[x]=y;val[y]+=sum[x];pushup(y);
        }
    void cut(int x)
        {
            access(x);splay(x);
            ch[0][x]=fa[ch[0][x]]=0;pushup(x);
        }
}T;
int last=1,tot=1,tr[N][26],fa[N],len[N],q,mask,ans;char s[N*3],op[N];
void extend(int c)
{
    int v=last,u=++tot;T.val[last=u]=1;
    len[u]=len[v]+1;
    while (v&&!tr[v][c]) tr[v][c]=u,v=fa[v];
    if (!v) fa[u]=1,T.link(u,1);
    else{
        int x=tr[v][c];
        if (len[x]==len[v]+1) fa[u]=x,T.link(u,x);
        else{
            int y=++tot;
            memcpy(tr[y],tr[x],sizeof(tr[y]));
            if (fa[x]) T.cut(x),T.link(y,fa[x]);
            fa[y]=fa[x];fa[x]=fa[u]=y;len[y]=len[v]+1;
            T.link(x,y);T.link(u,y);
            while (v&&tr[v][c]==x) tr[v][c]=y,v=fa[v];
        }
    }
}
void decode(int l)
{
    for (int i=0,tmp=mask;i<l;++i)
        tmp=(tmp*131+i)%l,swap(s[i],s[tmp]);
}
int main()
{
    scanf("%d %s",&q,s);int l=strlen(s);
    for (int i=0;i<l;++i) extend(s[i]-'A');
    while (q--){
        scanf(" %s %s",op,s);l=strlen(s);
        decode(l);
        if (op[0]=='Q')
        {
            int now=1;
            for (int i=0;i<l;++i) now=tr[now][s[i]-'A'];
            if (!now) ans=0;
            else T.access(now),T.splay(now),ans=T.val[now];
            printf("%d\n",ans);mask^=ans;
        }
        else for (int i=0;i<l;++i) extend(s[i]-'A');
    }
    return 0;
}

以上是关于[BZOJ2555] SubString的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 2555 2555: SubString (SAM+LCT)

BZOJ2555SubString(后缀自动机,Link-Cut Tree)

bzoj 2555 SubString(SAM+LCT)

bzoj2555: SubString

Bzoj2555 SubString

bzoj2555 SubString