非常好的一道KMP题。
吃透这道题,KMP就能彻底入门了。。。
首先题目求的是满足题意字符串的数量。
下文:i代表前i个字符,j代表前i个字符最长的前缀等于后缀的 前缀长度。
如果直接在求next的过程中求满足长度小于一半的前缀等于后缀数量。肯定会T
因为一个全是a的字符串。每次要推1/2*i次,才能得到j小于长度一半。有很多重复的过程(类似KMP)
我们要想办法省去这些过程。(可以想到如果i的j满足小于长度一半了,i+1,的j最多只能是j+1,我们如果每次不更新j的话可以去掉很多重复过程,而且总共最多执行n+m次 即线性复杂度。)
如果直接求任意长度的前缀等于后缀呢?
我们可以用num[i]=num[j]+1;(在求next的过程中)
这个关系式:想一下next数组的本质。。
有了num后怎么求出长度只能是字符串一半的子串数量呢?
显然,我们还可以模仿求next数组的过程,num_half[]i=num[j];
j是满足前缀等于后缀最大且,前缀长度小于字符串长度一半,的长度。
注意这里我们的num必须是包括本身字符串的数量才能推出num_half[i],所以再求num时,我们给num[0]赋值为1即可
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M = 1e6 + 10;
con