$luogu2375[NOI2014]$
\(problem\)
其中,\(next[i],next[next[i]],next[next[next[i]]]......\)都是这个前缀串i的公共前后缀,而且只有它们是公共前后缀
那么,我们其实只要在求\(next\)的过程中,顺便把这个公共前后缀的数量递推一下,就得到了一个弱化版的\(num数组\):可以重叠的公共前后缀数量,我们称之为\(ans\) 如何去除有重叠的?
还是看上面那张图
首先next数组有一个性质:\(next[i] < inext[i]<i\)
也就是说,一旦有一个递归了\(n\)层的\(next\),比原前缀i的长度的一半要小,那么这个\(next\)的递推出的答案\(ans\)就是\(i\)的\(num\)了
一个问题
假如我们拿到的串是\(1e6个'a'\),那么上面那个算法就会被卡成O(\(n^2\))道理的话大家可以想一想(每一次递归都只会把\(next[i]\)变小1)
那么我们需要做一个优化,来解决这个问题,而解决问题的核心就是:\(减少重复递归\)
减少重复递归......\(有没有想到什么?\)
没错,就是如同求\(next\)时一样的方法!
我们将递归用的变量\(j\)的值不更新,这样,求完了i的答案以后,\(j\)的位置一定在\(i/2\)的左边,也就是它已经满足要求了
这时再递归求解,总时间效率是\(O(n)\)的
#include <bits/stdc++.h>
using namespace std;
const ll MOD=1e9+7;
int n,fail[1000010],ans[1000010];
ll cnt;
char a[1000010];
int main() {
int T,i,j;
scanf("%d",&T);
while(T--) {
scanf("%s",a);
n=strlen(a);
memset(fail,0,sizeof(fail));
j=0;
ans[0]=0;
ans[1]=1;
for(i=1; i<n; i++) {
while(j&&(a[i]!=a[j])) j=fail[j];
j+=(a[i]==a[j]);
fail[i+1]=j;
ans[i+1]=ans[j]+1;
}
j=0;
cnt=1;
for(i=1; i<n; i++) {
while(j&&(a[i]!=a[j])) j=fail[j];
j+=(a[i]==a[j]);
while((j<<1)>(i+1)) j=fail[j];
cnt=(cnt*(ll)(ans[j]+1))%MOD;
}
printf("%lld\n",cnt);
}
return 0 ;
}
随机推荐
- Linux学习笔记(四) vi编辑器
一.vi 编辑器 vi 编辑器 (Visual Interface) 是所有 Unix 及 Linux 系统下标准的编辑器,相当于 Windows 系统中的记事本 它有三种模式,分别是: Comman ...
- 网页中添加QQ在线客服
方法一:调用本地已安装的QQ进行会话 <a href='tencent://message/?uin=QQ号码&Site=网站地址&Menu=yes'></a> ...
- BNUOJ 1260 Brackets Sequence
Brackets Sequence Time Limit: 1000ms Memory Limit: 65536KB This problem will be judged on PKU. Origi ...
- 九度oj 题目1053:互换最大最小数
题目1053:互换最大最小数 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:7538 解决:3049 题目描述: 输入一个数n,然后输入n个数值各不相同,调换数组中最大和最小的两个数,然后 ...
- (13)Corner Detection角点检测
import cv2 import numpy as np img=cv2.imread('opencv-corner-detection-sample.jpg') gray = cv2.cvtCol ...
- java中split以。点和|分割的问题
问题:想要按照点来切分字符串直接这样 String[] filep=filename.split("."); 结果得到一个空数组 解决方法: 法一:需要转义,改为:(注意是2个\\ ...
- JavaScript实现页面无刷新让时间走动
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- hdu 3555 Bomb 【数位DP】
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3555 题意:上一题是不要62 这个是"不要49" 代码: #include < ...
- bzoj2186【SDOI2008】沙拉公主的困惑
2186: [Sdoi2008]沙拉公主的困惑 Time Limit: 10 Sec Memory Limit: 259 MB Submit: 2363 Solved: 779 [id=2186& ...
- Android:使用SparseArray取代HashMap优化性能
之前看到一篇关于adapter的文章用到了SparseArray,所以在这里写写关于SparseArray的使用方法. SparseArray是官方针对安卓所写的容器,与HashMap类似,只是性能比 ...