zoukankan      html  css  js  c++  java
  • [bzoj 2555]Substring

    传送门

    Description

    给你一个字符串(init),要求你支持两个操作

    (1):在当前字符串的后面插入一个字符串

    (2):询问字符串s在当前字符串中出现了几次?(作为连续子串)

    你必须在线支持这些操作。

    Solution

    一个字符串出现的次数(=)它所对应的(Right)集合的大小(=)它在(parent)树上的孩子的(Right)集合的大小之和

    在本题中,我们需要动态的维护(parnet)树的形态,而这个是可以通过(LCT)实现的

    对于(val)值的修改,我们发现每次加点或删点都会影响一条到根路径上的所有点

    我们发现路径都是到根的,所以,这里的(LCT)就不需要(makeroot)操作了

    修改,是通过(lazy)标记实现哒


    Code 

    /**************************************************************
        Problem: 2555
        User: PaperCloud
        Language: C++
        Result: Accepted
        Time:14492 ms
        Memory:163144 kb
    ****************************************************************/
     
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #define get(x) (c[fa[x]][1]==x)
    #define MS 3000005
    #define MX 1200005
    char s[MS];
    int L,val[MX],lazy[MX];
    int fa[MX],c[MX][2];
    inline void upd(int x,int v)
    {
        if(!x)return;
        val[x]+=v;
        lazy[x]+=v;
    }
    inline void down(int x)
    {
        if(!lazy[x])return;
        upd(c[x][0],lazy[x]);
        upd(c[x][1],lazy[x]);
        lazy[x]=0;
    }
    inline bool nrt(int x)
    {
        return c[fa[x]][1]==x||c[fa[x]][0]==x;
    }
    inline void rotate(int x)
    {
        int y=fa[x],z=fa[y],l=get(x),r=l^1;
        if(nrt(y))c[z][get(y)]=x;fa[x]=z;
        fa[c[x][r]]=y;c[y][l]=c[x][r];
        fa[y]=x;c[x][r]=y;
    }
    inline void Splay(int x)
    {
        static int q[MX],top;q[top=1]=x;register int i;
        for(i=x;nrt(i);i=fa[i]) q[++top]=fa[i];
        for(;top;--top) down(q[top]);
        for(;nrt(x);rotate(x)) 
            if(nrt(fa[x])) rotate(get(x)^get(fa[x])?x:fa[x]);
    }
    inline void access(int x)
    {
        register int i;
        for(i=0;x;x=fa[i=x]) Splay(x),c[x][1]=i;
    }
    inline void cut(int x)
    {
        access(x);Splay(x);
        upd(c[x][0],-val[x]);
        fa[c[x][0]]=0;c[x][0]=0;
    }
    inline void link(int x,int y)
    {
        fa[x]=y;
        access(y);Splay(y);
        upd(y,val[x]);
    }
    inline void update(int x)
    {
        if(!x)return;
        Splay(x);
    }
    int fail[MX],ss[MX][26],step[MX];
    int last,cnt;
    inline void Insert(int x)
    {
        int p=last,np=++cnt;step[np]=step[p]+1;val[np]=1;
        for(;p&&!ss[p][x];p=fail[p]) ss[p][x]=np;
        if(!p)link(np,1),fail[np]=1;
        else
        {
            int q=ss[p][x];
            if(step[q]==step[p]+1)link(np,q),fail[np]=q;
            else
            {
                int nq=++cnt;step[nq]=step[p]+1;
                memcpy(ss[nq],ss[q],sizeof ss[q]);
                link(nq,fail[q]);cut(q);link(q,nq);link(np,nq);
                fail[nq]=fail[q];fail[q]=fail[np]=nq;
                for(;ss[p][x]==q;p=fail[p]) ss[p][x]=nq;
            }
        }
        last=np;
    }
    inline int Query(char *s,int L)
    {
        register int i,x=1;
        for(i=0;i<L;++i) x=ss[x][s[i]-'A'];
        update(x);return val[x];
    }
    int mask=0;
    int main()
    {
        last=cnt=1;
        int i,q,lastans=0;
        scanf("%d%s",&q,s+1);L=strlen(s+1);
        for(i=1;i<=L;++i) Insert(s[i]-'A');
        char opt[10];
        while(q--){
            scanf("%s%s",opt,s);
            L=strlen(s);
            int mk=mask;
            for(i=0;i<L;++i) mk=(mk*131+i)%L,std::swap(s[i],s[mk]);
            if(opt[0]=='A') for(i=0;i<L;++i) Insert(s[i]-'A');
            else printf("%d
    ",lastans=Query(s,L)),mask^=lastans;
        }
        return 0;
    }
    


    Blog来自PaperCloud,未经允许,请勿转载,TKS!

  • 相关阅读:
    wordpress取文章时间
    一个链接引发的血案---------服务器 IO及网络流量暴涨解决历程
    wordpres 自定义comment样式
    HTML中head里的内容经浏览器解析后全到body里了
    mir9-lua——《热血沙城》45度ARPG手游-Lua移植版
    MoonWarriors-lua——《雷电战机》游戏-Lua移植版
    《QQ欢乐斗地主》山寨版
    最好的ie版本检测方式
    css 超出部分显示省略号
    分享一个jquery插件,弥补一下hover事件的小小不足
  • 原文地址:https://www.cnblogs.com/PaperCloud/p/10345681.html
Copyright © 2011-2022 走看看