Description

懒得写背景了,给你一个字符串init,要求你支持两个操作

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

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

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

Solution

思路比较直观啊

首先没有插入的话,预处理好每个点 \(|right|\) 就好了

如果有插入的话我们发现实际上就是维护一个子树大小

每一次插入一个节点就相当于把父亲到根路径上的权值全部 \(+1\)

我们用 \(LCT\) 维护这个加边删边和路径加法的操作

每一次询问就是先找到这个串对应的节点 \(x\),如果没找到答案就是 \(0\),否则就是 \(|Right_x|\) 了

这题是有根树,不需要 \(makeroot\) 操作,写起来比较舒服

#include<bits/stdc++.h>
using namespace std;
const int N=2e6+10;
namespace LCT{
int ch[N][2],fa[N],la[N],w[N];
inline bool isrt(int x){return ch[fa[x]][0]!=x && ch[fa[x]][1]!=x;}
inline void mark(int x,int t){la[x]+=t;w[x]+=t;}
inline void pushdown(int x){
if(!la[x])return ;
mark(ch[x][0],la[x]);mark(ch[x][1],la[x]);
la[x]=0;
}
inline void rotate(int x){
int y=fa[x];bool t=ch[y][1]==x;
ch[y][t]=ch[x][!t];fa[ch[y][t]]=y;
ch[x][!t]=y;fa[x]=fa[y];
if(!isrt(y))ch[fa[y]][ch[fa[y]][1]==y]=x;
fa[y]=x;
}
inline void Push(int x){
if(!isrt(x))Push(fa[x]);
pushdown(x);
}
inline void splay(int x){
Push(x);
while(!isrt(x)){
int y=fa[x],p=fa[y];
if(isrt(y))rotate(x);
else if((ch[p][0]==y)==(ch[y][0]==x))rotate(y),rotate(x);
else rotate(x),rotate(x);
}
}
inline void access(int x){
int y=0;
while(x)splay(x),ch[x][1]=y,x=fa[y=x];
}
inline void link(int x,int y){
fa[x]=y;access(y);splay(y);splay(x);mark(y,w[x]);
}
inline void cut(int x){
access(x);splay(x);mark(ch[x][0],-w[x]);fa[ch[x][0]]=0;ch[x][0]=0;
}
inline int query(int x){
splay(x);return w[x];
}
}
char s[N],op[10];int Q,mask=0;
inline void decode(){
int len=strlen(s),t=mask;
for(int j=0;j<len;j++){
t=(t*131+j)%len;
swap(s[j],s[t]);
}
}
int ch[N][27],fa[N],len[N],cur=1,cnt=1;
inline void ins(int c){
int p=cur;cur=++cnt;len[cur]=len[p]+1;LCT::w[cur]=1;
for(;p && !ch[p][c];p=fa[p])ch[p][c]=cur;
if(!p)fa[cur]=1,LCT::link(cur,1);
else{
int q=ch[p][c];
if(len[q]==len[p]+1)fa[cur]=q,LCT::link(cur,q);
else{
int nt=++cnt;len[nt]=len[p]+1;
memcpy(ch[nt],ch[q],sizeof(ch[q]));
LCT::cut(q);LCT::link(nt,fa[q]);LCT::link(q,nt);LCT::link(cur,nt);
fa[nt]=fa[q];fa[q]=fa[cur]=nt;
for(;p && ch[p][c]==q;p=fa[p])ch[p][c]=nt;
}
}
}
inline int solve(int len){
int p=1;
for(int i=0;i<len;i++){
int c=s[i]-'A';
if(ch[p][c])p=ch[p][c];
else return 0;
}
return LCT::query(p);
}
int main(){
freopen("pp.in","r",stdin);
freopen("pp.out","w",stdout);
cin>>Q;
scanf("%s",s);
for(int i=0,le=strlen(s);i<le;i++)ins(s[i]-'A');
while(Q--){
scanf("%s%s",op,s);
decode();
int len=strlen(s),la;
if(op[0]=='A')for(int i=0;i<len;i++)ins(s[i]-'A');
else printf("%d\n",la=solve(len)),mask^=la;
}
return 0;
}

bzoj 2555: SubString的更多相关文章

  1. bzoj 2555: SubString 后缀自动机+LCT

    2555: SubString Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 688  Solved: 235[Submit][Status][Dis ...

  2. 字符串(LCT,后缀自动机):BZOJ 2555 SubString

    2555: SubString Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 1620  Solved: 471 Description 懒得写背景了 ...

  3. bzoj 2555 SubString(SAM+LCT)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2555 [题意] 给定一个字符串,可以随时插入字符串,提供查询s在其中作为连续子串的出现 ...

  4. ●BZOJ 2555 SubString

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2555题解: 后缀自动机+LCT 不难发现,对于输入的询问串,在自动机里trans后的到的状态 ...

  5. bzoj 2555 SubString——后缀自动机+LCT

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2555 要维护 right 集合的大小.因为 fa 会变,且 fa 构成一棵树,所以考虑用 L ...

  6. bzoj 2555 SubString —— 后缀自动机+LCT

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2555 建立后缀自动机,就可以直接加入新串了: 出现次数就是 Right 集合的大小,需要查询 ...

  7. 【刷题】BZOJ 2555 SubString

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

  8. bzoj 2555: SubString【后缀自动机+LCT】

    一直WA--找了半天错的发现居然是解密那里的mask其实是不能动的--传进去的会变,但是真实的那个不会变-- 然后就是后缀自动机,用LCT维护parent树了--注意不能makeroot,因为自动机的 ...

  9. BZOJ 2555: SubString 后缀自动机_LCT

    很水的一道题,就是有些细节没注意到. 比如说将调试信息误以为是最终结果而多调了20分钟QAQ ..... 我们注意到,每新加一个节点,改变的是该节点沿着 Parent 走一直走到根节点. 对应的,在 ...

随机推荐

  1. 洛谷 P3797 妖梦斩木棒

    https://www.luogu.org/problem/show?pid=3797 题目背景 妖梦是住在白玉楼的半人半灵,拥有使用剑术程度的能力. 题目描述 有一天,妖梦正在练习剑术.地面上摆放了 ...

  2. OO第一次总结

    第一次作业: 第一次作业的指导书发下来之后我按着上面的步骤一步一步的做了之后发现项目拉下来了,怎么开始码代码呢...然后在舍友的帮助下才知道怎么建包建类,然后对Java的语法又不是很了解,于是就先把C ...

  3. LeetCode & Q38-Count and Say-Easy

    String Description: The count-and-say sequence is the sequence of integers with the first five terms ...

  4. machine learning 之 logistic regression

    整理自Adrew Ng 的 machine learning课程week3 目录: 二分类问题 模型表示 decision boundary 损失函数 多分类问题 过拟合问题和正则化 什么是过拟合 如 ...

  5. Mosquito集群模式

    参考链接: http://blog.csdn.net/z729685731/article/details/70142182 http://blog.csdn.net/yuhaiyang457288/ ...

  6. bad interpreter:No such file or directory 解决方法

    今天在执行一个从网上考下来的脚本的时候,出现了下面的错误: Linux下面一个脚本死活也运行不了, 我检查了数遍,不可能有错. 提示:bad interpreter:No such file or d ...

  7. jdk的server模式修改无效(关于client和server模式)

    本机为64位操作系统,64位jdk,win10. 修改C:\Program Files\Java\jre8\lib\amd64\jvm.cfg无效. 我的文件的内容为: 原因参考如下: http:// ...

  8. ehcache.xml 属性大全

    属性大全 name:缓存名称. maxElementsInMemory:缓存最大个数. eternal:对象是否永久有效,一但设置了,timeout将不起作用. timeToIdleSeconds:设 ...

  9. SpringBoot(一):使用eclipse/idea创建springboot helloword工程

    eclipse如何创建spring boot工程: 第一步:首先打开eclipse,找到图中的下图的中“下三角”符号,选中"working sets"(表示将会把eclipse中的 ...

  10. 不错的ngix/redis/java/android学习地址

    http://blog.csdn.net/xlgen157387/article/details/50051543 徐刘根的博客,好像是“Java后端技术”微信公众号的建立者,反正看到不少关于他的博文 ...