传送门

题意简述:

要求在线支持两个操作

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

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


思路:

考虑用lctlctlct来动态维护samsamsam的rightrightright集合。

代码:

#include<bits/stdc++.h>
#define ri register int
using namespace std;
const int N=1200005;
char s[N];
int n;
string str;
inline void gets(int Mask){
	scanf("%s",s);
	str=s;
	for(ri i=0,up=str.size();i<up;++i){
		Mask=(Mask*131+i)%up;
		char t=str[i];
		str[i]=str[Mask];
		str[Mask]=t;
	}
}
int Mask=0;
namespace lct{
	int son[N][2],rev[N],siz[N],fa[N],add[N],stk[N],top=0;
	inline void pushnow(int p,int v){siz[p]+=v,add[p]+=v;}
	inline void pushdown(int p){if(add[p])pushnow(son[p][0],add[p]),pushnow(son[p][1],add[p]),add[p]=0;}
	inline bool isroot(int p){return !fa[p]||((p^son[fa[p]][0])&&(p^son[fa[p]][1]));}
	inline bool which(int p){return p^son[fa[p]][0];}
	inline void rotate(int x){
		int y=fa[x],z=fa[y],t=which(x);
		if(z&&!isroot(y))son[z][which(y)]=x;
		fa[y]=x,fa[x]=z,son[y][t]=son[x][t^1],son[x][t^1]=y;
		if(son[y][t])fa[son[y][t]]=y;
	}
	inline void splay(int x){
		stk[top=1]=x;
		for(ri p=x;!isroot(p);p=fa[p])stk[++top]=fa[p];
		while(top)pushdown(stk[top--]);
		while(!isroot(x)){if(!isroot(fa[x]))rotate(which(x)^which(fa[x])?x:fa[x]);rotate(x);}
	}
	inline void access(int x){for(ri y=0;x;x=fa[y=x])splay(x),son[x][1]=y;}
	inline void link(int x,int y){fa[x]=y,access(y),splay(y),pushnow(y,siz[x]);}
	inline void cut(int x){access(x),splay(x),pushnow(son[x][0],-siz[x]),fa[son[x][0]]=0,son[x][0]=0;}
}
namespace sam{
	int son[N][26],len[N],Link[N],tot=1,last=1;
	inline void insert(int x){
		int p=last,np=++tot;
		lct::siz[np]=1,len[last=np]=len[p]+1;
		while(p&&!son[p][x])son[p][x]=np,p=Link[p];
		if(!p)return lct::link(np,Link[np]=1);
		int q=son[p][x],nq;
		if(len[q]==len[p]+1)return lct::link(np,Link[np]=q);
		len[nq=++tot]=len[p]+1,memcpy(son[nq],son[q],sizeof(son[nq]));
		lct::link(nq,Link[nq]=Link[q]);
		lct::cut(q);
		lct::link(np,Link[np]=nq);
		lct::link(q,Link[q]=nq);
		while(p&&son[p][x]==q)son[p][x]=nq,p=Link[p];
	}
	inline void init(){scanf("%s",s+1);for(ri i=1,up=strlen(s+1);i<=up;++i)insert(s[i]-'A');}
	inline void add(){gets(Mask);for(ri i=0,up=str.size();i<up;++i)insert(str[i]-'A');}
	inline int query(){
		gets(Mask);
		int p=1;
		for(ri i=0,up=str.size();i<up;++i)if(!(p=son[p][str[i]-'A']))return 0;
		return lct::splay(p),lct::siz[p];
	}
}
int main(){
	scanf("%d",&n),sam::init();
	while(n--){
		char op[6];
		scanf("%s",op);
		if(op[0]=='A')sam::add();
		else{
			int ret=sam::query();
			Mask^=ret,cout<<ret<<'\n';
		}
	}
}

2019.03.01 bzoj2555: SubString(sam+lct)的更多相关文章

  1. 【BZOJ 2555】 2555: SubString (SAM+LCT)

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

  2. bzoj 2555 SubString(SAM+LCT)

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

  3. 【SPOJ】Longest Common Substring(后缀自动机)

    [SPOJ]Longest Common Substring(后缀自动机) 题面 Vjudge 题意:求两个串的最长公共子串 题解 \(SA\)的做法很简单 不再赘述 对于一个串构建\(SAM\) 另 ...

  4. 2019浙师大校赛(浙大命题)(upc复现赛)总结

    2019浙师大校赛(浙大命题)(upc复现赛)总结 早上九点开始.起得迟了,吃了早饭慌慌张张跑过去,刚到比赛就开始了. 开始分别从前往后和从后往前看题,一开始A题,第一发WA,第二次读题发现漏看了还有 ...

  5. BZOJ2555: SubString(后缀自动机,LCT维护Parent树)

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

  6. BZOJ2555 SubString【SAM + Link Cut Tree】

    BZOJ2555. SubString 要求在线询问一个串在原串中出现的次数,并且可以在原串末尾添加字符串 如果没有修改的话,考虑建出\(parent\)树之后统计每个\(endpos\)节点的\(r ...

  7. BZOJ 2594: [Wc2006]水管局长数据加强版(kruskal + LCT)

    Description SC省MY市有着庞大的地下水管网络,嘟嘟是MY市的水管局长(就是管水管的啦),嘟嘟作为水管局长的工作就是:每天供水公司可能要将一定量的水从x处送往y处,嘟嘟需要为供水公司找到一 ...

  8. 2019的hdu暑假作业(欢迎纠错)

    1219 遍历计数. #include<bits/stdc++.h> #define QAQ 0 using namespace std; ]; ]; int main(){ )){ me ...

  9. it's over | 2019 CSP-S 第二轮认证(超长预警)

    也许应该从Day -1(2019年11月14日周四)开始说起? 卑微的我们在学长的怂恿下终于...停课了(哇我们太菜了,只停一天半的课有个卵用 早读后我带头去办公室请假,飞哥很大方地答应了,同时免了我 ...

随机推荐

  1. 实验三:xen环境下的第一个虚拟机的安装

    实验名称: xen环境下的第一个虚拟机的安装 实验环境: 我们这里继续上面实验二来完成这个实验: 环境则是xen的安装环境,如下图: 开启虚拟机的的硬件辅助虚拟化功能: 实验要求: 这里我们通过安装b ...

  2. Bootstrap关闭当前页

       function doBack() {        var index = parent.layer.getFrameIndex(window.name);        parent.lay ...

  3. Python中xlrd和xlwt模块使用方法

    本文主要介绍可操作excel文件的xlrd.xlwt模块.其中xlrd模块实现对excel文件内容读取,xlwt模块实现对excel文件的写入. 安装xlrd和xlwt模块 xlrd和xlwt模块不是 ...

  4. Jquery中addClass方法不起作用的解决方案

    selected类是要在点击后添加上去的新样式,在点击后,发现没有变化,打开开发者工具,发现selected类已经添加成功了. 在这里没有显示成功的主要原因是后添加的样式表优先级更低,我暂时不清楚具体 ...

  5. Http协议和Https协议的安全性问题

    https://www.cnblogs.com/intsmaze/p/6009648.html https://blog.csdn.net/jeffleo/article/details/768630 ...

  6. 尚硅谷springboot学习30-docker安装mysql示例

    docker pull mysql 错误的启动示例 错误日志:需要设置密码 正确的启动 但还不能直接使用,因为没有做端口映射,外界无法连接 可用的启动 连接成功 几个高级的操作 指定配置文件 dock ...

  7. ArrayList实现动态数组原理

    addAll方法和申请数组大小函数 public boolean addAll(Collection<? extends E> c) { Object[] a = c.toArray(); ...

  8. Mybatis-PageHelper分页插件

    PageHelper.startPage 静态方法调用 除了 PageHelper.startPage 方法外,还提供了类似用法的 PageHelper.offsetPage 方法. 在你需要进行分页 ...

  9. Object.create() vs new SomeFunction() in javascript

    Object.create builds an object that inherits directly from the one passed as its first argument. Wit ...

  10. faster rcnn源码阅读笔记1

    自己保存的源码阅读笔记哈 faster rcnn 的主要识别过程(粗略) (开始填坑了): 一张3通道,1600*1600图像输入中,经过特征提取网络,得到100*100*512的feature ma ...