bzoj2555 SubString

题目描述

题接:

没有任何意义的LCT+SAM。

没有题解

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 600050
int n,m,mask,len;
char s[N];
void decode(int msk)
{
    len = strlen(s);
    for(int i=0;i<len;i++)
    {
        msk = (msk*131+i)%len;
        swap(s[i],s[msk]);
    }
}
struct LCT
{
    int ch[2*N][2],fa[2*N],s[2*N],sx[2*N],v[2*N];
    bool rt[2*N],res[2*N];
    void update(int u){s[u]=sx[u]+s[ch[u][0]]+s[ch[u][1]]+v[u];}
    void reser(int u)
    {
        res[u]^=1;
        swap(ch[u][0],ch[u][1]);
    }
    void pushdown(int u)
    {
        if(res[u])
        {
            res[u]=0;
            reser(ch[u][0]);
            reser(ch[u][1]);
        }
    }
    int tmp[2*N],tl;
    void down(int u)
    {
        tl=0;
        tmp[++tl]=u;
        while(!rt[u])u=fa[u],tmp[++tl]=u;
        while(tl)pushdown(tmp[tl]),tl--;
    }
    void rotate(int x)
    {
        int y = fa[x],k = (ch[y][1]==x);
        if(rt[y])rt[y]=0,rt[x]=1;
        else ch[fa[y]][ch[fa[y]][1]==y]=x;
        fa[x]=fa[y];
        ch[y][k] = ch[x][!k],fa[ch[x][!k]]=y;
        ch[x][!k] = y,fa[y] = x;
        update(y),update(x);
    }
    void splay(int x)
    {
        down(x);
        while(!rt[x])
        {
            int y = fa[x],z = fa[y];
            if(!rt[y])
                (ch[y][1]==x)^(ch[z][1]==y)?rotate(x):rotate(y);
            rotate(x);
        }
    }
    void access(int x)
    {
        int y = 0;
        while(x)
        {
            splay(x);
            sx[x]+=(s[ch[x][1]]-s[y]);
            rt[ch[x][1]]=1,rt[y]=0;
            ch[x][1]=y;
            update(x);
            y=x,x=fa[x];
        }
    }
    void link(int x,int y)
    {
        access(y);
        splay(y);
        fa[x]=y,sx[y]+=s[x];
        update(y);
    }
    void cut(int x,int y)
    {
        access(y);
        splay(y);
        fa[x]=ch[y][0]=0;
        rt[x]=1;
        update(y);
    }
    int query(int x)
    {
        access(x);
        splay(x);
        return v[x]+sx[x];
    }
    void clear(int x,int typ)
    {
        fa[x]=ch[x][0]=ch[x][1]=sx[x]=0;
        rt[x]=1;res[x]=0;
        s[x]=v[x]=typ;
    }
}tr;
struct node
{
    int pre,len,trs[28];
}p[2*N];
struct SAM
{
    int las,tot;
    SAM(){las=tot=1;}
    void insert(int c)
    {
        int np,nq,lp,lq;
        np=++tot;
        tr.clear(np,1);
        p[np].len = p[las].len+1;
        for(lp=las;lp&&!p[lp].trs[c];lp=p[lp].pre)
            p[lp].trs[c] = np;
        if(!lp)p[np].pre = 1,tr.link(np,1);
        else
        {
            lq = p[lp].trs[c];
            if(p[lq].len==p[lp].len+1)p[np].pre = lq,tr.link(np,lq);
            else
            {
                nq = ++tot;
                tr.clear(nq,0);
                p[nq] = p[lq];
                tr.link(nq,p[nq].pre);
                p[nq].len = p[lp].len+1;
                tr.cut(p[lq].pre,lq);
                tr.link(lq,nq);tr.link(np,nq);
                p[lq].pre = p[np].pre = nq;
                while(p[lp].trs[c]==lq)
                {
                    p[lp].trs[c] = nq;
                    lp = p[lp].pre;
                }
            }
        }
        las = np;
    }
}sam;
int main()
{
    scanf("%d%s",&m,s);
    len = strlen(s);
    tr.clear(1,0);
    for(int i=0;i<len;i++)
        sam.insert(s[i]-'A'+1);
    while(m--)
    {
        scanf("%s",s);
        if(s[0]=='Q')
        {
            scanf("%s",s);
            decode(mask);
            int u  = 1;
            for(int i=0;i<len;i++)
            {
                u = p[u].trs[s[i]-'A'+1];
                if(!u)break;
            }
            int ans = 0;
            if(u)ans = tr.query(u);
            mask^=ans;
            printf("%d\n",ans);
        }else
        {
            scanf("%s",s);
            decode(mask);
            for(int i=0;i<len;i++)
                sam.insert(s[i]-'A'+1);
        }
    }
    return 0;
}

 

posted @ 2018-12-15 10:00  LiGuanlin  阅读(103)  评论(0编辑  收藏  举报