• 【BZOJ2555】SubString


    Description

    懒得写背景了,给你一个字符串init,要求你支持两个操作
    
    (1):在当前字符串的后面插入一个字符串
    
    (2):询问字符串s在当前字符串中出现了几次?(作为连续子串)
    
    你必须在线支持这些操作。
    

    Input

    第一行一个数Q表示操作个数
    
    第二行一个字符串表示初始字符串init
    
    接下来Q行,每行2个字符串Type,Str 
    
    Type是ADD的话表示在后面插入字符串。

    Type是QUERY的话表示询问某字符串在当前字符串中出现了几次。

    为了体如今线操作。你须要维护一个变量mask,初始值为0

    这里写图片描写叙述

    读入串Str之后。使用这个过程将之解码成真正询问的串TrueStr。
    询问的时候,对TrueStr询问后输出一行答案Result
    然后mask = mask xor Result  
    插入的时候。将TrueStr插到当前字符串后面就可以。
    

    HINT:ADD和QUERY操作的字符串都须要解压

    Output

    Sample Input

    2
    
    
    
    A
    
    
    
    QUERY B
    
    
    
    ADD BBABBBBAAB
    

    Sample Output

    0
    

    HINT

    40 % 的数据字符串终于长度 <= 20000。询问次数<= 1000。询问总长度<= 10000

    100 % 的数据字符串终于长度 <= 600000。询问次数<= 10000,询问总长度<= 3000000

    新加数据一组–2015.05.20

    Source

    Ctsc模拟赛By 洁妹

    看题后想到
    SAM+LCT
    (事实上全然是听学长讲课时候知道的)(划掉这句话)
    刚開始认为可能会非常长写了写发现不是非常长也就不到150行
    对SAM的Parent树建LCT,给每一个状态一个权值
    然后就能够通过统计LCT的权值来统计出现次数了.
    一開始习惯性的在makeroot时候写了打上rev标记可是WA了?
    不知道为什么
    删掉之后又做了做微调发现自己又是RE又是TLE
    最后开大了数据范围就A了.
    这个题上经历了WA,RE,TLE,MLE真是感人至深.人生百态
    这里写图片描写叙述
    这里写图片描写叙述
    WA多了怂了一波开小号A了…
    可是还是非常慢!
    可是还是非常慢!
    可是还是非常慢!
    非常重要所以说三遍!
    居然跑了14sQAQ

    最后还是认为真是蛮难调的…

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #define MAXN 3000010
    using namespace std;
    int Q;
    char ch[MAXN],s[MAXN];
    string chars;
    int top,sta[MAXN];
    int mask,ans;
    void gets(int mask)
    {
        scanf("%s",s);
        chars=s;
        int len=chars.length();
        for (int j=0;j<len;j++) 
        {
            mask=(mask*131+j)%len;
            char t=chars[j];
            chars[j]=chars[mask];
            chars[mask]=t;
        }
    }
    struct lct
    {
        int ch[2],fa,flag,w;
        bool rev;
    }tree[MAXN];
    void modify(int x,int delta)
    {
        if (x)  tree[x].w+=delta,tree[x].flag+=delta;
    }
    void push_down(int x)
    {
        if (tree[x].flag)
        {
            modify(tree[x].ch[0],tree[x].flag);modify(tree[x].ch[1],tree[x].flag);
            tree[x].flag=0;
        }
    }
    bool is_root(int x)
    {
        return tree[tree[x].fa].ch[0]!=x&&tree[tree[x].fa].ch[1]!=x;
    }
    void rot(int x)
    {
        int y=tree[x].fa,z=tree[y].fa,l,r;
        l=(tree[y].ch[1]==x);r=l^1;
        if (!is_root(y))    tree[z].ch[tree[z].ch[1]==y]=x;
        tree[y].fa=x;tree[x].fa=z;tree[tree[x].ch[r]].fa=y;
        tree[y].ch[l]=tree[x].ch[r];tree[x].ch[r]=y;
    }
    void Splay(int x)
    {
        sta[++top]=x;
        for (int i=x;!is_root(i);i=tree[i].fa)  sta[++top]=tree[i].fa;
        while (top) push_down(sta[top--]);
        while (!is_root(x))
        {
            int y=tree[x].fa,z=tree[y].fa;
            if (!is_root(y))
            {
                if ((tree[y].ch[0]==x)^(tree[z].ch[0]==y))  rot(x);
                else    rot(y);
            }
            rot(x);
        }
    }
    void access(int x)
    {
        for (int i=0;x;i=x,x=tree[x].fa)    Splay(x),tree[x].ch[1]=i;
    }
    void make_root(int x)
    {
        access(x);Splay(x);//tree[x].rev^=1;
    }
    void link(int x,int y)
    {
        tree[x].fa=y;make_root(y);modify(y,tree[x].w);
    }
    void cut(int x)
    {
        make_root(x);modify(tree[x].ch[0],-tree[x].w);tree[tree[x].ch[0]].fa=0;tree[x].ch[0]=0;
    }
    struct sam
    {
        int cnt,last,p,q,np,nq;
        int a[MAXN][26],len[MAXN],fa[MAXN];
        sam()
        {
            last=++cnt;
        }
        void insert(int c)
        {
            p=last;last=np=++cnt;len[np]=len[p]+1;tree[np].w=1;
            while (!a[p][c]&&p) a[p][c]=np,p=fa[p];
            if (!p) fa[np]=1,link(np,1);
            else
            {
                q=a[p][c];
                if (len[q]==len[p]+1)   fa[np]=q,link(np,q);
                else
                {
                    nq=++cnt;len[nq]=len[p]+1;
                    memcpy(a[nq],a[q],sizeof(a[q]));
                    fa[nq]=fa[q];link(nq,fa[q]);
                    fa[q]=fa[np]=nq;cut(q);link(q,nq);link(np,nq);
                    while (a[p][c]==q)  a[p][c]=nq,p=fa[p];
                }
            }
        }
        int getans()
        {
            gets(mask);
            int st=1,Len=chars.length();
            for (int i=0;i<Len;i++)
                if (!(st=a[st][chars[i]-'A']))  return 0;
            Splay(st);
            return tree[st].w;
        }
    }sam;
    int main()
    {
        scanf("%d",&Q);scanf("%s",ch);
        int len=strlen(ch);
        for (int i=0;i<len;i++) sam.insert(ch[i]-'A');
        while (Q--)
        {
            scanf("%s",ch);
            if (ch[0]=='A')
            {
                gets(mask);
                len=chars.length();
                for (int i=0;i<len;i++) sam.insert(chars[i]-'A');
            }
            else
            {
                ans=sam.getans();mask^=ans;
                printf("%d
    ",ans);
            }
        }
    }
  • 相关阅读:
    SpringFramework中的BeanWrapper丶PropertyEditor
    Spring加载资源文件的方式
    kettle批量导入json数据
    Beanfactory与ApplicationContext
    fastjson的方法应用与java JSONObject
    算法 汽水瓶
    算法 简单密码
    算法 识别有效ip地址和掩码并做统计
    各类IP地址
    算法 密码验证合格程序
  • 原文地址:https://www.cnblogs.com/wzjhoutai/p/7363076.html
Copyright © 2020-2023  润新知