正题

题目链接:https://www.luogu.com.cn/problem/CF235C


题目大意

一个文本串\(s\)。询问\(n\)个匹配的本质不同的循环同构在文本串中出现了几次。


解题思路

我们匹配完原串之后,相当与每次在头部删去一个字符然后又在末尾加上一个字符。使用\(SAM\)匹配的话,发现每次在\(parents\)树上条就相当于删去头部的字符,因为\(parents\)树上的祖先是属于同一个\(endpos\)类的,所以后面的字符不会改变,我们一直跳到满足\(L\in [minlen_x,maxlen_x]\)的节点即可。

要求本质不同的话,就直接在统计过答案的点打上标记,后面不统计即可。

时间复杂度\(O(|s|+\sum_{i=1}^n|t|)\)


\(code\)

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=2e6+10;
int n,cnt,len[N],fa[N],siz[N],ch[N][26];
int last,ans,mark[N],c[N],p[N];
char s[N];
void Insert(int c){
int p=last,np=last=++cnt;
len[np]=len[p]+1;siz[np]++;
for(;p&&!ch[p][c];p=fa[p])ch[p][c]=np;
if(!p)fa[np]=1;
else{
int q=ch[p][c];
if(len[q]==len[p]+1)fa[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;
for(;p&&ch[p][c]==q;p=fa[p])ch[p][c]=nq;
}
}
return;
}
void solve(int p){
int l=strlen(s),L=0;
int x=1;
for(int i=0;i<l;i++){
int c=s[i]-'a';
while(x!=1&&!ch[x][c])
x=fa[x],L=len[x];
if(ch[x][c])x=ch[x][c],L++;
}
if(L==l&&mark[x]!=p)
mark[x]=p,ans+=siz[x];
for(int i=0;i<l-1;i++){
int c=s[i]-'a';
while(x!=1&&!ch[x][c])
x=fa[x],L=len[x];
if(ch[x][c])x=ch[x][c],L++;
if(L>l&&--L==len[fa[x]])
x=fa[x];
if(L==l&&mark[x]!=p)
mark[x]=p,ans+=siz[x];
}
return;
}
int main()
{
scanf("%s",s);int l=strlen(s);
cnt=last=1;
for(int i=0;i<l;i++)Insert(s[i]-'a');
for(int i=1;i<=cnt;i++) c[len[i]]++;
for(int i=1;i<=l;i++) c[i]+=c[i-1];
for(int i=1;i<=cnt;i++) p[c[len[i]]--]=i;
for(int i=cnt;i>=1;i--) siz[fa[p[i]]]+=siz[p[i]];
scanf("%d",&n);
for(int i=1;i<=n;i++){
ans=0;
scanf("%s",s),solve(i);
printf("%d\n",ans);
}
return 0;
}

CF235C-Cyclical Quest【SAM】的更多相关文章

  1. 【SAM】codevs3160-最长公共子串

    [题目大意] 求两个字符串的最长公共子串. [思路] 对第一个字符串建立后缀自动机,第二个字符串去匹配.cnt记录当前最长公共子串的长度,而ret记录答案. p代表位置指针,初始在rt位置. 对于第二 ...

  2. 【SAM】BZOJ2882-工艺

    [题目大意] 求一个循环数列的最小表示法. [思路] 最小表示法的正解:★ SAM乱搞,和前面的POJ那道一样.然而MLE了,当作学习一下map的用法^ ^ map的使用方法(来源:☆) 一.map的 ...

  3. 【SAM】BZOJ3998-弦论

    [题目大意] 给出一个字符串,求第k大的子串.(输入1表示子串可重复,0表示不可重复) [思路] 显然,k大子串是后缀自动机的经典题型,可以利用后缀自动机的性质来解决.对于字符串 [前铺1]" ...

  4. 【SAM】POJ1509-Glass Beads

    [题目大意] 求一个循环数列的最小表示法. [思路] 把原创复制一遍放在后面,建立SAM,从s按字典序开始跑长度L即可. 板子来源(作者见连接内):

  5. CF235C Cyclical Quest(SAM)

    /* 统计串的出现次数显然可以在自动机上匹配出来即可 但是每次都挨个匹配的话会时间爆炸 那么考虑我们把串复制一份, 然后一起在后缀自动机上跑, 当我们匹配长度大于该串长度的时候强行失配即可 可能会有旋 ...

  6. 【CodeForces - 235C】Cyclical Quest 【后缀自动机】

    题意 给出一个字符串s1和q个询问,每个询问给出一个字符串s2,问这个询问的字符串的所有不同的周期串在s1中出现的次数的和. 分析 对于s1建后缀自动机.对于询问的每个字符串s2,我们按照处理循环串的 ...

  7. Codeforces 235C Cyclical Quest 字符串 SAM KMP

    原文链接https://www.cnblogs.com/zhouzhendong/p/CF235C.html 题目传送门 -  CF235C 题意 给定一个字符串 $s$ ,多组询问,每组询问的形式为 ...

  8. CF235C Cyclical Quest

    题意 给定一个长度为\(n\)的母串 \(q\)组询问 这个串可以旋转(就是把最后一位丢到最前面这样子) 问这个串以及其旋转的串在给定的串中出现了多少次 Sol 旋转就把它复制一遍接在后面 然后就在\ ...

  9. 【SPOJ - LCS2】Longest Common Substring II【SAM】

    题意 求出多个串的最长公共子串. 分析 刚学SAM想做这个题的话最好先去做一下那道codevs3160.求两个串的LCS应该怎么求?把一个串s1建自动机,然后跑另一个串s2,然后找出s2每个前缀的最长 ...

随机推荐

  1. sentinel使用(结合OpenFeign)

    前提 需要先安装sentinel. 父项目POM pom.xml <?xml version="1.0" encoding="UTF-8"?> &l ...

  2. 获取SpringBean对象工具类

    获取SpringBean工具类 SpringBeanUtil代码如下: package com.meeno.wzq.util; import org.springframework.beans.Bea ...

  3. 浅谈 asp.net core web api

    希望通过本文能够了解如下内容: ControllerBase Attributes Action的返回值类型 ControllerBase 当我们开始实际上项目, 真正实操 anc 时, 肯定会用到 ...

  4. Windows10 Dev - Background Execution

    The Universal Windows Platform (UWP) introduces new mechanisms, which allow the applications to perf ...

  5. 【linux】vim常用命令

    转自:https://www.runoob.com/linux/linux-vim.html vi/vim 的使用 基本上 vi/vim 共分为三种模式,分别是命令模式(Command mode),输 ...

  6. linux 常用命令(三)——(centos7)MySql 5.7添加用户、删除用户与授权

    一.创建用户:以root用户登录到数据库进行用户创建 命令: CREATE USER 'username'@'host' IDENTIFIED BY 'password'; 例如: CREATE US ...

  7. 关于Junit中Assert已经过时

    在junit4.12之后,Assert就过时了,提供了TestCase来取代: 同样在TestCase中原本比较常见的一些方法也已经取消了,例如:assertNotEquals.assertThat. ...

  8. Web安全-CDN相关技术

    CDN介绍 CDN的全称是Content Delivery Network,即内容分发网络.CDN是构建在现有网络基础之上的智能虚拟网络,依靠部署在各地的边缘服务器,通过中心平台的负载均衡.内容分发. ...

  9. React事件处理、收集表单数据、高阶函数

    3.React事件处理.收集表单数据.高阶函数 3.1事件处理 class Demo extends React.Component { /* 1. 通过onXxx属性指定事件处理函数(注意大小写) ...

  10. Mybatis源码解析4——SqlSession

    上一篇文章中,我们介绍了 SqlSessionFactory 的创建过程,忘记了的,可以回顾一下,或者看下下面这张图也行. 接下来,可乐讲给大家介绍 Mybatis 中另一个重量级嘉宾--SqlSes ...