如果一个长度为n的字符串s,如果前[n/2]和后[n/2]位相同,并且是k-1度回文串,那么s为k度回文串,求一个字符串所有前缀的度数的和。
f[i]记录一下前i位的度数,没扫描以为更新一下前缀的正hash值和反hash值,如果这两个值相同,那么更新f[i]=f[i>>1]+1;并且累加度数,最后输出结果就行。
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
int n,m;
char s[10100000];
int f[10100000];
const ull x=257;
int main()
{
// freopen("in.txt","r",stdin);
while(~scanf("%s",s))
{
ull l=0,r=0,e=1;
int len=strlen(s);
memset(f,0,sizeof f);
ull ans=0;
for (int i=0; i<len; i++)
{
l=l*x+s[i];
r=s[i]*e+r;
e*=x;
if (l==r) ans+=(f[i+1]=f[(i+1)>>1]+1);
}
cout<<ans<<endl;
}
return 0;
}