【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);
        }
    }
}
时间: 2024-10-12 18:11:28

【BZOJ2555】SubString的相关文章

【BZOJ2555】SubString 后缀自动机+LCT

[BZOJ2555]SubString Description 懒得写背景了,给你一个字符串init,要求你支持两个操作         (1):在当前字符串的后面插入一个字符串         (2):询问字符串s在当前字符串中出现了几次?(作为连续子串)         你必须在线支持这些操作. Input 第一行一个数Q表示操作个数         第二行一个字符串表示初始字符串init         接下来Q行,每行2个字符串Type,Str         Type是ADD的话表示在

【BZOJ2555】SubString(后缀自动机,Link-Cut Tree)

[BZOJ2555]SubString(后缀自动机,Link-Cut Tree) 题面 BZOJ 题解 这题看起来不难 每次要求的就是\(right/endpos\)集合的大小 所以搞一个\(LCT\)维护一下\(SAM\)的\(Parent\)树就好了 但是代码一点都不好写(我还是对着黄学长的调的...) 于是乎我也学着魔改了一下\(LCT\) #include<iostream> #include<cstdio> #include<cstdlib> #include

【BZOJ-2555】SubString 后缀自动机 + LinkCutTree

2555: SubString Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 1936  Solved: 551[Submit][Status][Discuss] Description 懒得写背景了,给你一个字符串init,要求你支持两个操作    (1):在当前字符串的后面插入一个字符串    (2):询问字符串s在当前字符串中出现了几次?(作为连续子串)    你必须在线支持这些操作. Input 第一行一个数Q表示操作个数    第二行一

【BZOJ2555】SubString 后缀自动机 暴力

转载请注明出处:http://blog.csdn.net/vmurder/article/details/42915143 题解:正解是LCT+SAM. 但是出题人太神以至于不屑于卡你,所以只写个SAM然后暴力维护就好了. 这样虽然很不科学,但是可以比正解快三倍. 我是太困了吧,写挂了调了好久(发呆了好久然后秒调过,或者说半眯着眼睛睡了一会) 代码: <span style="font-family:KaiTi_GB2312;font-size:18px;">#includ

【LeetCode】Substring with Concatenation of All Words 解题报告

[题目] You are given a string, S, and a list of words, L, that are all of the same length. Find all starting indices of substring(s) in S that is a concatenation of each word in L exactly once and without any intervening characters. For example, given:

【leetcode】Substring with Concatenation of All Words

Substring with Concatenation of All Words You are given a string, S, and a list of words, L, that are all of the same length. Find all starting indices of substring(s) in S that is a concatenation of each word in L exactly once and without any interv

【leetcode】Substring with Concatenation of All Words (hard) ★

You are given a string, S, and a list of words, L, that are all of the same length. Find all starting indices of substring(s) in S that is a concatenation of each word in L exactly once and without any intervening characters. For example, given:S: "b

【LeetCode】双指针 two_pointers(共47题)

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica } [3]Longest Substring Without Repeating Characters [11]Container With Most Water [15]3Sum [16]3Sum Closest [18]4Sum [19]Remove Nth Node From End of List [26]Remove Duplicates from Sorted

【LeetCode】字符串 string(共112题)

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica } [3]Longest Substring Without Repeating Characters [5]Longest Palindromic Substring [6]ZigZag Conversion [8]String to Integer (atoi) [10]Regular Expression Matching [12]Integer to Roman