C. Cyclical Quest

time limit per test:3 seconds
memory limit per test:512 megabytes
input:standard input
output:

standard output

Some days ago, WJMZBMR learned how to answer the query "how many times does a string x occur in a string s" quickly by preprocessing the string s. But now he wants to make it harder.

So he wants to ask "how many consecutive substrings of s are cyclical isomorphic to a given string x". You are given string s and nstrings xi, for each string xi find, how many consecutive substrings of s are cyclical isomorphic to xi.

Two strings are called cyclical isomorphic if one can rotate one string to get the other one. 'Rotate' here means 'to take some consecutive chars (maybe none) from the beginning of a string and put them back at the end of the string in the same order'. For example, string "abcde" can be rotated to string "deabc". We can take characters "abc" from the beginning and put them at the end of "de".

Input

The first line contains a non-empty string s. The length of string s is not greater than 106 characters.

The second line contains an integer n (1 ≤ n ≤ 105) — the number of queries. Then n lines follow: the i-th line contains the string xi — the string for the i-th query. The total length of xi is less than or equal to 106 characters.

In this problem, strings only consist of lowercase English letters.

Output

For each query xi print a single integer that shows how many consecutive substrings of s are cyclical isomorphic to xi. Print the answers to the queries in the order they are given in the input.

Examples

input
baabaabaaa
5
a
ba
baa
aabaa
aaba
output
7
5
7
3
5
input
aabbaa
3
aa
aabb
abba
output
2
3
3

Solution

题目大意:给出一个字符串T,再给出N个字符串S,每次回答字符串S的所有循环串在T中出现次数,重复的不计入答案. 这里的循环串的意思 每次将首位字符置于末位置后形成的新串.

后缀自动机

先对模板串建后缀自动机,然后对于询问的每个串分别放到自动机上匹配,并统计答案.

具体的过程就是,对于询问的每个串S,构建成串SS,然后放到自动机上匹配,匹配的方法和求LCS时类似,如果匹配到的位置$>N$且匹配的长度$>=N$那么说明匹配出了一种循环串,这时候可以考虑统计这个循环串的答案.

就是在询问之前拓扑排序递推出每个节点的贡献,然后如果此时匹配到的点在Parent树中的节点刚好能够表示长度为N的子串,那么直接累加贡献即可,否则沿Parent指针跳到合适的节点再累加贡献即可.

这样累加贡献显然会出现重复的情况,那么只需要在每个节点上再打上一个标记,如果此次查询未利用这个节点的贡献,则计入贡献,否则跳过,即可得解.

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#define MAXN 1000010
char S[MAXN<<1];
int N,Q;
namespace SAM
{
int son[MAXN<<1][27],len[MAXN<<1],par[MAXN<<1],size[MAXN<<1];
int last,sz=1,root=1;
inline void Init() {last=root;}
inline void Extend(int c)
{
int cur=++sz,p=last;
len[cur]=len[p]+1; size[cur]=1;
while (p && !son[p][c]) son[p][c]=cur,p=par[p];
if (!p) par[cur]=root;
else
{
int q=son[p][c];
if (len[p]+1==len[q]) par[cur]=q;
else
{
int nq=++sz;
memcpy(son[nq],son[q],sizeof(son[nq]));
len[nq]=len[p]+1;
par[nq]=par[q];
while (p && son[p][c]==q) son[p][c]=nq,p=par[p];
par[cur]=par[q]=nq;
}
}
last=cur;
}
inline void Build() {Init(); for (int i=1; i<=N; i++) Extend(S[i]-'a'+1);}
int st[MAXN],id[MAXN<<1];
inline void Pre()
{
for (int i=1; i<=sz; i++) st[len[i]]++;
for (int i=1; i<=N; i++) st[i]+=st[i-1];
for (int i=1; i<=sz; i++) id[st[len[i]]--]=i;
for (int i=sz; i>=1; i--)
size[par[id[i]]]+=size[id[i]];
}
int flag[MAXN<<1];
inline void Query()
{
int now=root,L=0,ans=0;
for (int i=1; i<=N+N; i++)
{
int c=S[i]-'a'+1;
if (son[now][c]) L++,now=son[now][c];
else
{
while (now && !son[now][c]) now=par[now];
if (!now)
now=root,L=0;
else
L=len[now]+1,now=son[now][c];
}
if (i>N && L>=N)
{
int tmp=now;
while (tmp && !(N>=len[par[tmp]]+1 && N<=len[tmp]))
tmp=par[tmp];
if (!tmp) tmp=root;
if (flag[tmp]!=Q+1) ans+=size[tmp],flag[tmp]=Q+1;
}
}
printf("%d\n",ans);
}
}using namespace SAM;
int main()
{
scanf("%s",S+1); N=strlen(S+1);
SAM::Build(); SAM::Pre();
scanf("%d",&Q);
while (Q--)
{
scanf("%s",S+1); N=strlen(S+1);
for (int i=1; i<=N; i++) S[N+i]=S[i];
SAM::Query();
}
return 0;
}

  

【Codeforces235C】Cyclical Quest 后缀自动机的更多相关文章

  1. Codeforces 235C Cyclical Quest - 后缀自动机

    Some days ago, WJMZBMR learned how to answer the query "how many times does a string x occur in ...

  2. CF 235C. Cyclical Quest [后缀自动机]

    题意:给一个主串和多个询问串,求询问串的所有样子不同的周期同构出现次数和 没有周期同构很简单就是询问串出现次数,|Right| 有了周期同构,就是所有循环,把询问串复制一遍贴到后面啊!思想和POJ15 ...

  3. Codeforces Round #146 (Div. 1) C - Cyclical Quest 后缀自动机+最小循环节

    #include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk mak ...

  4. 【CF235C】Cyclical Quest(后缀自动机)

    [CF235C]Cyclical Quest(后缀自动机) 题面 洛谷 题解 大致翻译: 给定一个串 然后若干组询问 每次也给定一个串 这个串可以旋转(就是把最后一位丢到最前面这样子) 问这个串以及其 ...

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

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

  6. Cyclical Quest CodeForces - 235C (后缀自动机)

    Cyclical Quest \[ Time Limit: 3000 ms\quad Memory Limit: 524288 kB \] 题意 给出一个字符串为 \(s\) 串,接下来 \(T\) ...

  7. Cyclical Quest CodeForces - 235C 后缀自动机

    题意: 给出一个字符串,给出一些子串,问每个子串分别在母串中圆环匹配的次数, 圆环匹配的意思是将该子串拆成两段再首位交换相接的串和母串匹配,比 如aaab变成baaa,abaa,aaba再进行匹配. ...

  8. 后缀自动机(SAM)

    *在学习后缀自动机之前需要熟练掌握WA自动机.RE自动机与TLE自动机* 什么是后缀自动机 后缀自动机 Suffix Automaton (SAM) 是一个用 O(n) 的复杂度构造,能够接受一个字符 ...

  9. 【学习笔记】浅析后缀自动机(SAM)及基础应用

    解决子串相关问题的强大工具 我们知道一个长度为 \(n\) 的字符串中所有的子串数目为 \(O(n^2)\) 个,这很大程度上限制了我们对某些子串相关问题的研究.所以有没有解决方案,使得我们可以在可承 ...

随机推荐

  1. 每天一个设计模式-4 单例模式(Singleton)

    每天一个设计模式-4 单例模式(Singleton) 1.实际生活的例子 有一天,你的自行车的某个螺丝钉松了,修车铺离你家比较远,而附近的五金店有卖扳手:因此,你决定去五金店买一个扳手,自己把螺丝钉固 ...

  2. 转 threejs中3D视野的缩放实现

    Threejs基础部分学习知道透视相机new THREE.PerspectiveCamera(fov, aspect , near,far)中. fov视野角(拍摄距离)越大,场景中的物体越小.fov ...

  3. 在Android中,使用Kotlin的 API请求简易方法

    原文标题:API request in Android the easy way using Kotlin 原文链接:http://antonioleiva.com/api-request-kotli ...

  4. iOS 应用程序生命周期

    开发应用程序都要了解其生命周期. 今天我们接触一下iOS应用程序的生命周期, iOS的入口在main.m文件: int main(int argc, char * argv[]) { @autorel ...

  5. SlidingMenu 侧滑菜单的用法

    很多APP都有侧滑菜单的功能,部分APP左右都是侧滑菜单~SlidingMenu 这个开源项目可以很好帮助我们实现侧滑功能,将侧滑菜单引入项目的方式很多中,先通过例子介绍各种引入方式,然后给大家展示个 ...

  6. oracle容器化docker解决方案

    Docker提供了轻量级的虚拟化,它几乎没有任何额外开销. 提供了一个从开发到上线均一致的环境. 开发效率:一是我们想让开发环境尽量贴近生产环境 二是我们想快速搭建开发环境   基于docker研发小 ...

  7. response和request的区别以及常见问题解决

    request是请求,即客服端发来的请求 response是响应,是服务器做出的响应 --------------------------------------------------------- ...

  8. freeradius整合AD域作anyconncet认证服务器

    一.服务器要求 Radius服务器:centos6.6.hostname.selinux  disabled.stop iptables AD域服务器:Windows Server 2008 R2 E ...

  9. 【java开发】ubuntu常用命令及环境搭建

    学习第一天,今天内容相对简单,主要就是ubuntu一些常用命令及常规操作,后续涉及到环境的搭建,也会在本文再更. ubuntu环境搭建 第一种 也是最简单最方便的 通过vm虚拟机软件,下载iso镜像进 ...

  10. [python]获取网页中内容为汉字的字符串的判断

    实际上是这样,将获取到网页中表单内容与汉字字符串作比较,即: a = request.POST['a'] if a == '博客园': print 'ok' else: print 'false' a ...