P5212-SubString【LCT,SAM】
正题
题目链接:https://www.luogu.com.cn/problem/P5212
题目大意
开始一个字符串\(S\),有\(n\)次操作
- 在\(S\)末尾加入一个字符串
- 询问一个串在\(S\)中出现了多少次
强制在线
解题思路
强制在线的话,只有\(\text{SAM}\)能够支持动态插字符了,但是我们平时统计答案的时候要先做一次拓扑排序然后上传信息。
这里要动态维护\(\text{parents}\)树的话用\(\text{LCT}\)就好了,就是链修改加单点查询,然后因为根是指定的可以少写很多操作。
时间复杂度\(O(\ (n+S)\log |S|)\)
code
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>
using namespace std;
const int N=6e5*2+10;
int n,cnt,len[N],fa[N],ch[N][26];
char st[N];
struct LCT{
int t[N][2],lazy[N],w[N],fa[N];
stack<int> s;
bool Nroot(int x)
{return fa[x]&&((t[fa[x]][0]==x)||(t[fa[x]][1]==x));}
bool Direct(int x)
{return t[fa[x]][1]==x;}
void Add(int x,int val)
{if(x)w[x]+=val,lazy[x]+=val;return;}
void PushDown(int x){
if(!lazy[x])return;
if(t[x][0])Add(t[x][0],lazy[x]);
if(t[x][1])Add(t[x][1],lazy[x]);
lazy[x]=0;return;
}
void Rotate(int x){
int y=fa[x],z=fa[y];
int xs=Direct(x),ys=Direct(y);
int w=t[x][xs^1];
if(Nroot(y))t[z][ys]=x;
t[y][xs]=w;t[x][xs^1]=y;
if(w)fa[w]=y;fa[y]=x;fa[x]=z;
return;
}
void Splay(int x){
int y=x;s.push(x);
while(Nroot(y))y=fa[y],s.push(y);
while(!s.empty())PushDown(s.top()),s.pop();
while(Nroot(x)){
y=fa[x];
if(!Nroot(y))Rotate(x);
else if(Direct(y)==Direct(x))
Rotate(y),Rotate(x);
else Rotate(x),Rotate(x);
}
return;
}
void Access(int x){
for(int y=0;x;y=x,x=fa[x])
Splay(x),t[x][1]=y;
return;
}
void Link(int x,int y)//x为单点,y为树
{fa[x]=y;Access(y);Splay(y);Add(y,w[x]);return;}
void Cut(int x)//将x切断为单点
{Access(x);Splay(x);Add(t[x][0],-w[x]);fa[t[x][0]]=0;t[x][0]=0;return;}
}T;
void decode(char *s,int l,int mask) {
for (int j=0;j<l;j++) {
mask=(mask*131+j)%l;
swap(s[j],s[mask]);
}
return;
}
int insert(int c,int p){
int np=++cnt;len[np]=len[p]+1;T.w[np]++;
for(;p&&!ch[p][c];p=fa[p])ch[p][c]=np;
if(!p)fa[np]=1,T.Link(np,1);
else{
int q=ch[p][c];
if(len[p]+1==len[q])fa[np]=q,T.Link(np,q);
else{
int nq=++cnt;len[nq]=len[p]+1;
memcpy(ch[nq],ch[q],sizeof(ch[nq]));
fa[nq]=fa[q];fa[np]=fa[q]=nq;
T.Cut(q);T.Link(nq,fa[nq]);
T.Link(np,nq);T.Link(q,nq);
for(;p&&ch[p][c]==q;p=fa[p])ch[p][c]=nq;
}
}
return np;
}
int main()
{
scanf("%d",&n);
scanf("%s",st);int l=strlen(st);
int p=cnt=1;int mask=0;
for(int i=0;i<l;i++)
p=insert(st[i]-'A',p);
while(n--){
char op[5];
scanf("%s %s",op,st);l=strlen(st);
decode(st,l,mask);
if(op[0]=='Q'){
int x=1;
for(int i=0;i<l;i++)
if(!ch[x][st[i]-'A'])
{x=0;break;}
else x=ch[x][st[i]-'A'];
if(!x)puts("0");
else{
T.Splay(x);
printf("%d\n",T.w[x]);
mask^=T.w[x];
}
}
else{
for(int i=0;i<l;i++)
p=insert(st[i]-'A',p);
}
}
return 0;
}
P5212-SubString【LCT,SAM】的更多相关文章
- 【BZOJ1036】【LCT版】树的统计Count
Description 一 棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. ...
- 2594. [WC2006]水管局长数据加强版【LCT+最小生成树】
Description SC省MY市有着庞大的地下水管网络,嘟嘟是MY市的水管局长(就是管水管的啦),嘟嘟作为水管局长的工作就是:每天供水公司可能要将一定量的水从x处送往y处,嘟嘟需要为供水公司找到一 ...
- bzoj 4032: [HEOI2015]最短不公共子串【dp+SAM】
第一.二问: 就是最小的最长公共长度+1,设f[i][j]为a匹配到i,b匹配到j,第一问的转移是f[i][j]=(a[i]==b[j]?f[i-1][j-1]+1:0),第二问的转移是f[i][j] ...
- bzoj 2780: [Spoj]8093 Sevenk Love Oimaster【广义SAM】
AC自动机比较简单,把询问串做成AC自动机然后模板串边跑变更新即可 SAM是把模板串做成广义SAM,然后每个节点存有几个模板串经过,具体方法是每次更新暴力向上跳直到有时间戳我不会证为什么时间复杂度是对 ...
- SPOJ-LCS Longest Common Substring 【后缀自动机】
题目分析: 用没出现过的字符搞拼接.搞出right树,找right集合的最小和最大.如果最小和最大分居两侧可以更新答案. 代码: #include<bits/stdc++.h> using ...
- Codeforces 919D Substring 【拓扑排序】+【DP】
<题目链接> 题目大意:有一个具有n个节点,m条边的有向图,每个点对应一个小写字母,现在给出每个顶点对应的字母以及有向边的连接情况,求经过的某一条路上相同字母出现的最多次数.如果次数无限大 ...
- 【算法专题】后缀自动机SAM
后缀自动机是用于识别子串的自动机. 学习推荐:陈立杰讲稿,本文记录重点部分和感性理解(论文语言比较严格). 刷题推荐:[后缀自动机初探],题目都来自BZOJ. [Right集合] 后缀自动机真正优于后 ...
- BZOJ2555 SubString 【后缀自动机 + LCT】
题目 懒得写背景了,给你一个字符串init,要求你支持两个操作 (1):在当前字符串的后面插入一个字符串 (2):询问字符串s在当前字符串中出现了几次?(作为连续子串) 你必须在线支持这些操作. 输入 ...
- ZJOI2012网络 题解报告【LCT】
题目描述 有一个无向图G,每个点有个权值,每条边有一个颜色.这个无向图满足以下两个条件: 对于任意节点连出去的边中,相同颜色的边不超过两条. 图中不存在同色的环,同色的环指相同颜色的边构成的环. 在这 ...
随机推荐
- 五、Abp vNext 基础篇丨博客聚合功能
介绍 业务篇章先从客户端开始写,另外补充一下我给项目起名的时候没多想起的太随意了,结果后面有些地方命名冲突了需要通过手动using不过问题不大. 开工 应用层 根据第三章分层架构里面讲到的现在我们模型 ...
- C#异步编程2
- uwp 的个人名片
xml code ---------------------------------------------------------------------- <Page x:Class=&qu ...
- 五:HttpServletResponse对象
一.HttpServletResponse对象介绍 HttpServletResponse对象代表服务器的响应.这个对象中封装了向客户端发送数据.发送响应头,发送响应状态码的方法.查看HttpServ ...
- [ASP.NET MVC]@Html.ActionLik重载
一 Html.ActionLink("linkText","actionName") 该重载的第一个参数是该链接要显示的文字,第二个参数是对应的控制器的方法, ...
- 关于Mysql 5.7版本 一直出现时间 不对 链接出现问题 以及日志的问题 解决方案
问题: mysql版本号: 报错信息: Cause:java.sql.SQLException: The server time zone value '�й���ʱ��' is unrecogni ...
- 初识apache DBCP连接池
连接案例: 首先:我们使用的是mysql数据库,所以要有一个mysql和java的JDBCjar包: 然后是DBCP中的两个jar包,DBCP使用的话,需要两个包: dbcp.jar和pool.jar ...
- 挂载redhat镜像创建本地yum源
上传镜像文件到/mnt文件夹下,或者上传到其他文件夹下 挂载镜像路径/mnt/cdrom 在mnt文件夹下创建cdrom文件夹 创建命令:mkdir cdrom 挂载镜像命令:mount rhel- ...
- uniapp H5 打包并部署到 nginx
个人也是了百度了挺久的了,花费的时间( 俩个半小时 ) uniapp 的打包首先要先配置,配置好了才能去进行打包,如图所示. 这只是第一步. 注意: 1.运行基础路径最好用 ./ ,如果配置了其他请自 ...
- 【开发工具】Postman保姆级入门教程
目录 一.简单使用 1. 创建命名空间 2. 创建新集合 3. 按模块整理接口 二.使用环境变量 1. 创建环境与环境变量 2. 使用环境变量 3. 登录后自动更新环境变量 转载请注明出处 一.简单使 ...