思路:
扩展kmp,预处理出nxt数组相加,对于全部匹配的前缀减1就行了
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 1e6 + 10;
ll nxt[maxn],ans;
void getnext(string t)
{
memset(nxt,0,sizeof(nxt));
ll len=t.length();
nxt[0]=len;
ll a,p;
a=1;
while( a<len && t[a]==t[a-1]) a++; // 求出长度为1的时候 解为多少
nxt[1]=a-1;
a=1;
for(ll i=2;i<len;i++) // 后续的按照算法来就好
{
p=a+nxt[a]-1;
if((i-1)+nxt[i-a] < p ) nxt[i]=nxt[i-a];// 第一种情况 没有超过等于的部分
else // 超过的话就不好直接用nxt的定义 需要后续的遍历
{
ll j = (p - i + 1) > 0 ? (p - i + 1) : 0;
while(i + j < len && t[i+j] == t[j]) j++;
nxt[i]=j;
a=i;
}
}
}
int main()
{
ios::sync_with_stdio(false);
int t;
cin>>t;
while (t --)
{
string s;
cin>>s;
ans = 0;
getnext(s);
for (int i = 0;i < s.size();i ++)
{
ans += nxt[i];
if (nxt[i]+i==s.size()) ans--;
}
cout<<ans<<endl;
}
return 0;
}