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

这个题打了好久,原来是预处理倍增T粉了;

首先这题肯定是跟KMP有关的,利用nxt数组的性质。

因为前缀和后缀不能相交,所以我们需要暴跳nxt直到2*j<=i为止,才算符合不重叠;

然后如果要求num数组,是还要再暴跳到0的,然后统计跳了几次,但是这个东西可以在求nxt的时候顺便求出来,所以暴跳到一个就可以直接得出答案了。

然后我并不知道复杂度。。。

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<algorithm>
  4. #include<cstring>
  5. #define RG register
  6. using namespace std;
  7. const int N=1000050;
  8. const int Mod=1000000007;
  9. int nxt[N],cnt[N],len,T,f[N][18],num[N];
  10. long long ans;
  11. char s[N];
  12. void make_nxt() {
  13. cnt[1]=1;int j=0;
  14. for(RG int i=2;i<=len;i++){
  15. while(j&&s[j+1]!=s[i]) j=nxt[j];
  16. if(s[j+1]==s[i]) j++;
  17. nxt[i]=j;cnt[i]=cnt[j]+1;
  18. }
  19. }
  20. void work(){
  21. int j=0;ans=1;
  22. for(RG int i=2;i<=len;i++){
  23. while(j&&s[j+1]!=s[i]) j=nxt[j];
  24. if(s[j+1]==s[i]) j++;
  25. while(2*j>i) j=nxt[j];
  26. ans*=(cnt[j]+1);if(ans>Mod)ans%=Mod;
  27. }
  28. }
  29. int main() {
  30. freopen("1.in","r",stdin);
  31. freopen("1.out","w",stdout);
  32. scanf("%d",&T);
  33. while(T--) {
  34. scanf("%s",s+1),len=strlen(s+1);
  35. memset(nxt,0,sizeof(nxt));
  36. memset(num,0,sizeof(num));
  37. memset(cnt,0,sizeof(cnt));
  38. make_nxt();work();printf("%lld\n",ans);
  39. }
  40. }

  

bzoj 3670: [Noi2014]动物园的更多相关文章

  1. 字符串(KMP):BZOJ 3670 [Noi2014]动物园

    3670: [Noi2014]动物园 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1521  Solved: 813[Submit][Status] ...

  2. BZOJ 3670: [Noi2014]动物园【KMP变形 】

    3670: [Noi2014]动物园 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 2738  Solved: 1475[Submit][Status ...

  3. BZOJ 3670 NOI2014 动物园 KMP+dp

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3670 题意概述:令num[i]表示字符串由1~i的字符形成的前缀中不相重叠的相同前后缀的数 ...

  4. BZOJ 3670: [Noi2014]动物园 [KMP]

    求这玩意: 对于字符串S的前i个字符构成的子串,既是它的后缀同时又是它的前缀,并且该后缀与该前缀不重叠,将这种字符串的数量记作num[i] 对1,000,000,007取模的结果 n≤5,L≤1,00 ...

  5. 【BZOJ】3670: [Noi2014]动物园

    http://www.lydsy.com/JudgeOnline/problem.php?id=3670 题意:太水了= = #include <bits/stdc++.h> using ...

  6. 【BZOJ】3670: [Noi2014]动物园(KMP)

    题目 传送门:QWQ 分析 像求next一样求num. 第二次求next时加上不超过一半的条件. 时间复杂度: $ \huge O ( n ) $ 代码 // luogu-judger-enable- ...

  7. 3670: [Noi2014]动物园

    题目链接 题意:给n个字符串,求出每个字符串的num值,加1后相乘.num[i]表示1~i中,有多少没有重叠的公共前缀后缀. 分析: kmp中p数组表示最大的公共前缀后缀.设一cnt数组,表示1~i中 ...

  8. bzoj千题计划250:bzoj3670: [Noi2014]动物园

    http://www.lydsy.com/JudgeOnline/problem.php?id=3670 法一:KMP+st表 抽离nxt数组,构成一棵树 若nxt[i]=j,则i作为j的子节点 那么 ...

  9. NOI2014 动物园

    3670: [Noi2014]动物园 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 174  Solved: 92[Submit][Status] D ...

随机推荐

  1. jquery.base64.js 中文乱码处理

    c# 转码:Convert.ToBase64String(Encoding.UTF8.GetBytes(str)) js 解码:$.base64.atob(this.options.valids, t ...

  2. c语言的流程控制

    1. 流程控制 ● 顺序结构:默认的流程结构.按照书写顺序执行每一条语句. ● 选择结构:对给定的条件进行判断,再根据判断结果来决定执行哪一段代码. ● 循环结构:在给定条件成立的情况下,反复执行某一 ...

  3. ABP module-zero +AdminLTE+Bootstrap Table+jQuery权限管理系统第十六节--SignalR与ABP框架Abp.Web.SignalR及扩展

    SignalR简介 SignalR是什么? ASP.NET SignalR 是为 ASP.NET 开发人员提供的一个库,可以简化开发人员将实时 Web 功能添加到应用程序的过程.实时 Web 功能是指 ...

  4. day7、用户登陆出现-bash-4.1$错误的原因

    有时候在使用用户登陆Linux系统时会出现-bash-4.1$错误,不显示用户名,路径信息. 原因:用户家目录里面与环境变量有关的文件被删除所导致的 .bash_profile .bashrc 这两个 ...

  5. Ubuntu 14.4 Django模型迁移到数据库提示 LookupError: unknown encoding: utf8mb4 解决方法

    由于数据库中需要存储emoji表情,因此需要mysql支持utf8mb4,参考前面的文章升级数据库. 但是由于服务器上面的python-mysqldb连接包版本为1.2.3不支持utf8mb4,因此报 ...

  6. 掌握sklearn系列——1 学会加载数据

    我们直接看代码: from sklearn import datasets #读取三组数据,前两个用于分类,第三个用于回归 iris = datasets.load_iris() digits = d ...

  7. 谷哥的小弟学前端(11)——JavaScript基础知识(2)

    探索Android软键盘的疑难杂症 深入探讨Android异步精髓Handler 具体解释Android主流框架不可或缺的基石 站在源代码的肩膀上全解Scroller工作机制 Android多分辨率适 ...

  8. Android - shape圆形画法(oval)

    shape圆形画法(oval) 本文地址: http://blog.csdn.net/caroline_wendy 1. 创建一个目录drawable, 用于存放xml类型的图片资源; 2. 在dra ...

  9. 错误代码: 1054 Unknown column &#39;t.createUsrId&#39; in &#39;group statement&#39;

    1.错误描写叙述 1 queries executed, 0 success, 1 errors, 0 warnings 查询:select count(t.id),t.`createUserId` ...

  10. SpringBoard 无法启动应用程序(错误:-3)

    临时不知道错误的细节原因,重新启动模拟器就好了. 先记录下.