String s of length n is called k-palindrome, if it is a palindrome itself, and its prefix and suffix of length
are (k - 1)-palindromes. By definition, any string (even empty) is 0-palindrome.
Let's call the palindrome degree of string s such a maximum number k, for which s is k-palindrome. For example, "abaaba" has degree equals to 3.
You are given a string. Your task is to find the sum of the palindrome degrees of all its prefixes.
Input
The first line of the input data contains a non-empty string, consisting of Latin letters and digits. The length of the string does not exceed 5·106. The string is case-sensitive.
Output
Output the only number — the sum of the polindrome degrees of all the string's prefixes.
Examples
input
a2A
output
1
input
abacaba
output
6
题意: 每个字符串都有一个等级,非回文字符串等级为0,回文串等级为两侧字符串等级+1。输出字符串所有前缀串的等级和。
分析: 判断回文可以用字符串hash解决,维护正向和反向hash值即可。之后这道题其实就转化为线性dp了,定义dp[i]为以str[i]结尾的字符串阶数,状态转移方程为:如果str[1~i]是回文串,dp[i] = dp[i/2]+1,否则dp[i] = 0,不需要更新。
具体代码如下:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cstring>
#define P 131
#define int unsigned long long
using namespace std;
char str[5000005];
int dp[5000005];//dp[i]表示以str[i]结尾的字符串阶数
int h1[5000005], h2[5000005];//正序hash值与逆序hash值
int p[5000005];
signed main()
{
scanf("%s", str+1);
p[0] = 1;
int ans = 0, len = strlen(str+1);
for(int i = 1; i <= len; i++)
{
p[i] = p[i-1]*P;
h1[i] = h1[i-1]*P+str[i];
h2[i] = h2[i-1]+str[i]*p[i-1];
if(h1[i] != h2[i])//如果不是回文就跳过
continue;
dp[i] = dp[i/2]+1;
ans += dp[i];
}
cout << ans;
return 0;
}