【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\n",ans);
        }
    }
}
posted @ 2017-08-15 08:25  wzjhoutai  阅读(186)  评论(0编辑  收藏  举报