传送门:洛谷P2375

一直到写到这道题目才发现我一直都理解了假的KMP……fail数组:fail[i]为从1-i(包含i)在内的字符串,相同的最长前后缀长度。

那么我们可以先思考暴力:先求出所有的fail,再不断往上跳,那么跳到的节点中(fail<<1)<i的个数即为num值。但这样的复杂度太高了,所以我们要进一步优化。

可以发现每一个节点所指向的fail节点是唯一的,但一个点可能是多个节点的fail,这是一个树形的关系。且在这个树形关系上,越靠近根节点的fail值也就越小。所以我们逐层标记Num值,直到找到符合条件的节点,则这个节点所标记的值就是它&它上方所有节点的个数。(若该点满足条件,则在它之上的一定满足)。

#include <bits/stdc++.h>
using namespace std;
#define maxn 10000
#define ll long long
#define p 1000000007
int fail[maxn], num[maxn];
char s[maxn];
ll solve()
{
ll ans = ;
int len = strlen(s + );
memset(fail, , sizeof(fail));
memset(num, , sizeof(num));
num[] = ;
for(int i = , j = ; i <= len; i ++)
{
while(j && s[i] != s[j + ]) j = fail[j];
if(s[i] == s[j + ]) j ++;
fail[i] = j;
num[i] = num[j] + ;
}
for(int i = , j = ; i <= len; i ++)
{
while(j && s[i] != s[j + ]) j = fail[j];
if(s[i] == s[j + ]) j ++;
while((j << ) > i) j = fail[j];
ans = (num[j] + ) * ans;
ans %= p;
}
return ans;
} int main()
{
int T;
scanf("%d", &T);
while(T --)
{
scanf("%s", s + );
printf("%lld\n", solve());
}
return ;
}

最新文章

  1. 使用Hudson进行持续集成
  2. 微软Edge 内嵌的JavaScript 引擎即将开源
  3. Android抓包方法(一)之Fiddler代理
  4. c#中如何执行存储过程
  5. 微信开放平台API开发资料
  6. JSBinding + SharpKit / 生成JavaScript绑定
  7. Qt_5_3_MSVC2012-编译QFtp-qt5编译QFtp
  8. ios特性访问器方法(setter和getter)
  9. [AngularJS] ui-router: named views
  10. bootstrap table 服务器端分页例子分享
  11. 让ie8支持foreach
  12. Jupyter Notebook通过latex输出pdf
  13. android控制文件:ViewPager+Fragment+GridView使用(与AndroidQuery框架结合)
  14. Scrum Meeting Alpha - 10
  15. 2018-2019-2 网络对抗技术 20165325 Exp1 PC平台逆向破解
  16. Latex使用:在latex中添加算法模块
  17. python 第三库卸载办法
  18. javascript学习之this
  19. 07 Maven 使用Nexus创建私服
  20. php中heredoc的使用方法

热门文章

  1. JavaScript--文本框中只允许输入数字的操作(其他字符不显示)
  2. JS高度融合入门笔记(二)
  3. python基础小知识,is和==的区别,编码和解码
  4. Leecode刷题之旅-C语言/python-83删除排序链表中的重复元素
  5. 006---Python基本数据类型--集合
  6. Python3爬虫(九) 数据存储之关系型数据库MySQL
  7. python 字符串输入、输出函数print input raw_input
  8. 基于Ubuntu Server 16.04 LTS版本安装和部署Django之(三):设置上传文件夹权限(这里测试用完全共享)
  9. deepin linux 安装/启动jeakins报错:处理
  10. MySQL☞where与like