描述


http://www.lydsy.com/JudgeOnline/problem.php?id=3670

对于一个字符串,求出num数组,其中num[i]表示前i个字符构成的字串中不相重合的相同前后缀共有多少对.

3670: [Noi2014]动物园

Time Limit: 10 Sec  Memory Limit: 512 MB
Submit: 1740  Solved: 923
[Submit][Status][Discuss]

Description

近日,园长发现动物园中好吃懒做的动物越来越多了。例如企鹅,只会卖萌向游客要吃的。为了整治动物园的不良风气,让动物们凭自己的真才实学向游客要吃的,园长决定开设算法班,让动物们学习算法。

某天,园长给动物们讲解KMP算法。

园长:“对于一个字符串S,它的长度为L。我们可以在O(L)的时间内,求出一个名为next的数组。有谁预习了next数组的含义吗?”

熊猫:“对于字符串S的前i个字符构成的子串,既是它的后缀又是它的前缀的字符串中(它本身除外),最长的长度记作next[i]。”

园长:“非常好!那你能举个例子吗?”

熊猫:“例S为abcababc,则next[5]=2。因为S的前5个字符为abcab,ab既是它的后缀又是它的前缀,并且找不到一个更长的字符串满足这个性质。同理,还可得出next[1] = next[2] = next[3] = 0,next[4] = next[6] = 1,next[7] = 2,next[8] = 3。”

园长表扬了认真预习的熊猫同学。随后,他详细讲解了如何在O(L)的时间内求出next数组。

下课前,园长提出了一个问题:“KMP算法只能求出next数组。我现在希望求出一个更强大num数组一一对于字符串S的前i个字符构成的子串,既是它的后缀同时又是它的前缀,并且该后缀与该前缀不重叠,将这种字符串的数量记作num[i]。例如S为aaaaa,则num[4] = 2。这是因为S的前4个字符为aaaa,其中a和aa都满足性质‘既是后缀又是前缀’,同时保证这个后缀与这个前缀不重叠。而aaa虽然满足性质‘既是后缀又是前缀’,但遗憾的是这个后缀与这个前缀重叠了,所以不能计算在内。同理,num[1] = 0,num[2] = num[3] = 1,num[5] = 2。”

最后,园长给出了奖励条件,第一个做对的同学奖励巧克力一盒。听了这句话,睡了一节课的企鹅立刻就醒过来了!但企鹅并不会做这道题,于是向参观动物园的你寻求帮助。你能否帮助企鹅写一个程序求出num数组呢?

特别地,为了避免大量的输出,你不需要输出num[i]分别是多少,你只需要输出对1,000,000,007取模的结果即可。

Input

第1行仅包含一个正整数n ,表示测试数据的组数。随后n行,每行描述一组测试数据。每组测试数据仅含有一个字符串S,S的定义详见题目描述。数据保证S 中仅含小写字母。输入文件中不会包含多余的空行,行末不会存在多余的空格。

Output

包含 n 行,每行描述一组测试数据的答案,答案的顺序应与输入数据的顺序保持一致。对于每组测试数据,仅需要输出一个整数,表示这组测试数据的答案对 1,000,000,007 取模的结果。输出文件中不应包含多余的空行。

Sample Input

3
aaaaa
ab
abcababc

Sample Output

36
1
32

HINT

n≤5,L≤1,000,000

Source

分析


在做kmp的自匹配时,顺便记录一个cnt数组,其中cnt[i]表示第i个字符需要进行几次i=fail[i]到达0,也就是如果失配时跳转到i位置,包括i位置,之前共有多少可以作为失配时跳转对象的(也就是有多少满足和后面某一后缀相同的前缀).第二遍做子匹配时,将失配指针一直跳到小于等于i/2的位置j,此时cnt[j]就是共有多少满足的相同前缀后缀组即num[i].(手画画更清楚点?)

p.s.第二次匹配时如果i位置跳转到了k,那么k之后的任意数k'都满足k'>i/2,那么在i+1时,k'+1>(i+1)/2,所以如果在i位置跳转到了k,在i+1位置继续从k+1位置即可.

 #include <cstdio>

 const int mod=1e9+;
const int maxn=1e6+;
int ans;
char c[maxn];
int fail[maxn],cnt[maxn]; void kmp(){
int j=;
fail[]=,cnt[]=;
for(int i=;c[i];i++){
while(j&&c[j+]!=c[i]) j=fail[j];
if(c[i]==c[j+]) j++;
fail[i]=j;
cnt[i]=cnt[j]+;
}
j=;ans=;
for(int i=;c[i];i++){
while(j&&c[j+]!=c[i]) j=fail[j];
if(c[i]==c[j+]) j++;
while((j<<)>i) j=fail[j];
ans=((long long)ans*(long long)(cnt[j]+))%mod;
}
} int main()
{
int n;
scanf("%d",&n);
while(n--){
scanf("%s",c+);
kmp();
printf("%d\n",ans);
}
return ;
}

BZOJ_3670_[NOI2014]_动物园_(kmp)的更多相关文章

  1. UOJ #5. 【NOI2014】动物园 扩大KMP

    第一次NOI称号. ... 扩展假设知道KMP如果. .. . 就是水题了. ... #5. [NOI2014]动物园 统计提交情况 描写叙述 提交 近日.园长发现动物园中好吃懒做的动物越来越多了.比 ...

  2. 【BZOJ3670】【NOI2014】动物园(KMP算法)

    [BZOJ3670]动物园(KMP算法) 题面 BZOJ 题解 神TM阅读理解题 看完题目之后 想暴力: 搞个倍增数组来跳\(next\) 每次暴跳\(next\) 复杂度\(O(Tnlogn)\) ...

  3. BZOJ_3670_[Noi2014]动物园_KMP

    BZOJ_3670_[Noi2014]动物园_KMP Description 近日,园长发现动物园中好吃懒做的动物越来越多了.例如企鹅,只会卖萌向游客要吃的.为了整治动物园的不良风气,让动物们凭自己的 ...

  4. uoj #5. 【NOI2014】动物园 kmp

    #5. [NOI2014]动物园 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://uoj.ac/problem/5 Description 近日 ...

  5. uoj #5. 【NOI2014】动物园

    #5. [NOI2014]动物园 近日,园长发现动物园中好吃懒做的动物越来越多了.例如企鹅,只会卖萌向游客要吃的.为了整治动物园的不良风气,让动物们凭自己的真才实学向游客要吃的园长决定开设算法班,让 ...

  6. Oracle学习总结_day03_day04_条件查询_排序_函数_子查询

    本文为博主辛苦总结,希望自己以后返回来看的时候理解更深刻,也希望可以起到帮助初学者的作用. 转载请注明 出自 : luogg的博客园 谢谢配合! day03_条件查询_排序_函数 清空回收站: PUR ...

  7. C Primer Plus_第6章_循环_编程练习

    1.题略 #include int main(void) { int i; char ch[26]; for (i = 97; i <= (97+25); i++) { ch[i-97] = i ...

  8. 转:HIBERNATE一些_方法_@注解_代码示例---写的非常好

    HIBERNATE一些_方法_@注解_代码示例操作数据库7步骤 : 1 创建一个SessionFactory对象 2 创建Session对象 3 开启事务Transaction : hibernate ...

  9. 迅为4412开发板Linux驱动教程——总线_设备_驱动注册流程详解

    本文转自:http://www.topeetboard.com 视频下载地址: 驱动注册:http://pan.baidu.com/s/1i34HcDB 设备注册:http://pan.baidu.c ...

随机推荐

  1. FromHandle函数

    一 FromHandle() MFC 实际上是对内核对象HANDLE(如CDC的m_hDC,CWnd的m_hWnd)封装了这个句柄有关的所有操作,一个类生成一个新对象的时候这个句柄是无效的,要获得这个 ...

  2. jsf taglib定义函数

    创建文件   在文件中添加function标签 <function> <function-name>getFileContent</function-name> & ...

  3. html调用applet

    1.相同目录下 <applet code="*.class" width=250 height=50> </applet> 指定applet类名称,appl ...

  4. Entity Framework 使用sql语句分页(查询单表)

    1.查询单表 var pageSize = 2;//条数 var pageIndex = 2;//索引 var sql = @" SELECT D.* FROM ( SELECT ROW_N ...

  5. 关于AVAudioPlayer

    IOS中有三种播放音频的方式:AVAudioPlayer.音频服务.音频队列. 此文主要讲AVAudioPlayer,其他两个请见相关文章. AVAudioPlayer在AVFoundation框架下 ...

  6. 线程池读取List<T>实例

    private static readonly Object ThisLock = new object(); private static readonly AutoResetEvent AutoR ...

  7. PHP pear安装出现 Warning: require_once(Structures/Graph.php)...错误

    今天在WINDOWS安装pear,一路无阻很顺利安装完成,接着想安装下pear email包来玩下,但接下来却报: Warning: require_once(Structures/Graph.php ...

  8. 安装"MySQLdb"一波三折.

    在慕课网学习课程"Python操作MySQL数据库",安装"MySQLdb"时遇到问题. 先是找错地方: 百度搜索"Mysql for Python& ...

  9. bzoj1901:Zju2112 Dynamic Rankings

    思路:树套树,我写了两种,一种是线段树套splay,线段树维护区间信息,splay维护第k大,一种是树状数组套权值线段树(并不是什么可持久化线段树,只不过是动态开点罢了,为什么网上一大堆题解都是可持久 ...

  10. Linux错误码的含义

    C Name Value Description EPERM 1 Operation not permitted ENOENT 2 No such file or directory ESRCH 3 ...