Codeforces 235C Cyclical Quest 字符串 SAM KMP
原文链接https://www.cnblogs.com/zhouzhendong/p/CF235C.html
题目传送门 - CF235C
题意
给定一个字符串 $s$ ,多组询问,每组询问的形式为一个字符串 $T$ ,问 $S$ 有多少个子串与 $T$ 循环同构。(如果 $S$ 有多个相同子串都同构,则算多次)
$|S|\leq 10^6,\sum |T|\leq 10^6$
题解
以后坚决不念诗了!中午作死念诗,下午就被一个傻逼错误续了 3 个多钟头。
做法:
给 $S$ 建一个 SAM ,然后对于每一个 $T$ KMP 一下,找到最大循环节,在 SAM 上面走一走就可以了。
代码
#include <bits/stdc++.h>
#define right _47hurnf
using namespace std;
typedef long long LL;
const int N=1000005;
int n,m;
char s[N];
struct SAM{
int Next[26],fa,Max;
}t[N<<1];
int tax[N],id[N<<1],right[N<<1];
int size;
void init(){
memset(t,0,sizeof t);
size=1,t[0].Max=-1;
for (int i=0;i<26;i++)
t[0].Next[i]=1;
}
int extend(int p,int c){
if (t[p].Next[c]&&t[p].Max+1==t[t[p].Next[c]].Max)
return t[p].Next[c];
int np=++size,q,nq;
t[np].Max=t[p].Max+1;
for (;!t[p].Next[c];p=t[p].fa)
t[p].Next[c]=np;
q=t[p].Next[c];
if (t[p].Max+1==t[q].Max)
t[np].fa=q;
else {
nq=++size;
t[nq]=t[q],t[nq].Max=t[p].Max+1;
t[q].fa=t[np].fa=nq;
for (;t[p].Next[c]==q;p=t[p].fa)
t[p].Next[c]=nq;
}
return np;
}
int Fail[N];
int KMP(char s[],int n){
Fail[0]=Fail[1]=0;
for (int i=2;i<=n;i++){
int k=Fail[i-1];
while (k>0&&s[i]!=s[k+1])
k=Fail[k];
Fail[i]=k+(s[k+1]==s[i]?1:0);
}
int x=Fail[n];
while (x>0&&n%(n-x)!=0)
x=Fail[x];
return n-x;
}
int main(){
scanf("%s",s+1);
n=strlen(s+1);
init();
for (int i=1,p=1;i<=n;i++)
p=extend(p,s[i]-'a'),right[p]++;
for (int i=1;i<=size;i++)
tax[t[i].Max]++;
for (int i=1;i<=n;i++)
tax[i]+=tax[i-1];
for (int i=1;i<=size;i++)
id[tax[t[i].Max]--]=i;
for (int i=size;i>=1;i--)
right[t[id[i]].fa]+=right[id[i]];
scanf("%d",&m);
while (m--){
scanf("%s",s+1);
int len=strlen(s+1),r=KMP(s,len);
LL ans=0;
int p=1,Matched=0;
for (int i=1;i<=len;i++){
int c=s[i]-'a';
while (!t[p].Next[c])
p=t[p].fa,Matched=t[p].Max;
p=t[p].Next[c];
Matched++;
}
for (int i=1;i<=r;i++){
int c=s[i]-'a';
while (!t[p].Next[c])
p=t[p].fa,Matched=t[p].Max;
p=t[p].Next[c];
Matched++;
while (t[t[p].fa].Max>=len)
p=t[p].fa,Matched=t[p].Max;
if (Matched>=len)
ans+=right[p];
}
printf("%I64d\n",ans);
}
return 0;
}
Codeforces 235C Cyclical Quest 字符串 SAM KMP的更多相关文章
- Codeforces 235C. Cyclical Quest
传送门 写的时候挺蛋疼的. 刚开始的时候思路没跑偏,无非就是建个SAM然后把串开两倍然后在SAM上跑完后统计贡献.但是卡在第二个样例上就是没考虑相同的情况. 然后开始乱搞,发现会出现相同串的只有可能是 ...
- Codeforces 235C Cyclical Quest - 后缀自动机
Some days ago, WJMZBMR learned how to answer the query "how many times does a string x occur in ...
- CodeForces 235C Cyclical Quest(后缀自动机)
[题目链接] http://codeforces.com/contest/235/problem/C [题目大意] 给出一个字符串,给出一些子串,问每个子串分别在母串中圆环匹配的次数,圆环匹配的意思是 ...
- Codeforces 316G3 Good Substrings 字符串 SAM
原文链接http://www.cnblogs.com/zhouzhendong/p/9010851.html 题目传送门 - Codeforces 316G3 题意 给定一个母串$s$,问母串$s$有 ...
- Codeforces 452E Three strings 字符串 SAM
原文链接https://www.cnblogs.com/zhouzhendong/p/CF542E.html 题目传送门 - CF452E 题意 给定三个字符串 $s1,s2,s3$ ,对于所有 $L ...
- Codeforces 873F Forbidden Indices 字符串 SAM/(SA+单调栈)
原文链接https://www.cnblogs.com/zhouzhendong/p/9256033.html 题目传送门 - CF873F 题意 给定长度为 $n$ 的字符串 $s$,以及给定这个字 ...
- Codeforces 700E. Cool Slogans 字符串,SAM,线段树合并,动态规划
原文链接https://www.cnblogs.com/zhouzhendong/p/CF700E.html 题解 首先建个SAM. 一个结论:对于parent树上任意一个点x,以及它所代表的子树内任 ...
- CF 235C. Cyclical Quest [后缀自动机]
题意:给一个主串和多个询问串,求询问串的所有样子不同的周期同构出现次数和 没有周期同构很简单就是询问串出现次数,|Right| 有了周期同构,就是所有循环,把询问串复制一遍贴到后面啊!思想和POJ15 ...
- Cyclical Quest CodeForces - 235C (后缀自动机)
Cyclical Quest \[ Time Limit: 3000 ms\quad Memory Limit: 524288 kB \] 题意 给出一个字符串为 \(s\) 串,接下来 \(T\) ...
随机推荐
- [Linux]PHP-FPM与NGINX的两种通讯方式
一.通过监听TCP端口通讯 php-fpm.d/www.conf ; The address on which to accept FastCGI requests. ; Valid syntaxes ...
- iOS9 新功能:Support Universal Links,iOS10 openUrl新函数
先看官方文档:https://developer.apple.com/library/ios/documentation/General/Conceptual/AppSearch/UniversalL ...
- 计算机中K到底是1000还是1024?
1000和1024的争论,其实是传输领域和存储领域概念不清引起的;在传输领域,1秒钟传输多少字位(即b,bit),肯定是用10进制表示,所以是1kb=1000b,即1秒钟传输1000个比特位;就好像: ...
- STM32应用实例十一:基于SPI和AD7192的数据采集
在开发臭氧发生器的时,我们需要一个高分辨率的AD采集,于是选择了AD7192,选择这款ADC的原因比较简单.首先它是24位的符合我们的精度要求:其次它自带时钟,便于节省空间:第三他又4路单端或2路差分 ...
- LeetCode(78):子集
Medium! 题目描述: 给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集). 说明:解集不能包含重复的子集. 示例: 输入: nums = [1,2,3] 输出: [ [3 ...
- Redis扩展
Redis扩展下载地址:https://windows.php.net/downloads/pecl/releases/redis/ PHP怎么安装redis扩展 http://www.php.cn/ ...
- laravel 兜底路由
在 Laravel 5.6 中,引入了兜底路由功能.所谓兜底路由,就是当路由文件中定义的所有路由都无法匹配用户请求的 URL 时,用来处理用户请求的路由,在此之前,Laravel 都会通过异常处理器为 ...
- MySQL数据库查询中的特殊命令
第一: MySQL的安装 下载MySQL软件,修改安装路径之后 安装数据库MySQL5.7.18 第一步:数据库MySQL5.7.18可以在官网上下载对应的版本,下载地址:http://www.f ...
- Linux基础三:linux目录结构和目录文件的浏览、管理及维护
目录文件的浏览.管理及维护(一) 1.Linux文件系统的层次结构 1)Linux文件系统的树状结构:在Linux或UNIX操作系统中,所有的文件和目录都被组织成一个以根节点开始的倒置的树状结构. 2 ...
- git bash here 的 ~/.bashrc 配置文件。和 vue/cli 3. 0 的 .vuerc文件(preset )
今天就来讲一下git有关的小技巧,.bashrc文件是用户配置文环境变量的文件,每次git bash会首先运行里面的内容 1.自动运行 每次进入git bash都会先读取.bashrc里面的内容,因此 ...