题目描述
由于一饭班长表示各种鸭梨,美丽的纪中决定历史性地启用第二饭堂。而部分领导觉得,二饭依山傍水,环境优美,未免有不和谐的事情(你懂的)发生,决定到二饭巡视同学们用餐时的就座情况。
为了应付这一情况,同学们决定联合起来“布阵”。
方便起见,同学们已经把座位情况抽象成一个长度为
n
n
n 的仅含数字及字母的字符串,他们想请你帮忙算算这个字符串的和谐程度。
已知一个字符串被称为
k
−
k-
k−回文串的充要条件是它自身是回文串,并且它长为
n
/
2
n/2
n/2(下取整)的前缀和后缀是
(
k
−
1
)
−
(k-1)-
(k−1)−回文串。根据定义,任意字符串(包括空串)都是
0
−
0-
0−回文串。
一个字符串的回文度数就是这个字符串的k的最大值。
而对于一个给定的字符串,它的和谐程度就是其所有前缀的回文度数之和。
你的任务就是算出这个和谐程度具体是多少。
输入格式
一行一个仅包含数字和字母的字符串。
输出格式
一行一个整数表示这个字符串的和谐程度。
样例输入
abacaba
样例输出
6
数据范围与提示
对于
30
%
30\%
30% 的数据字符串长度不超过
1000
1000
1000
对于
70
%
70\%
70% 的数据字符串长度不超过
100000
100000
100000
对于
100
%
100\%
100% 的数据字符串长度不超过
5000000
5000000
5000000
题解
题意我花了点时间理解,大概可以概括为求这个字符串包含了多少“层”回文串k就是多少,但是这道题完全没必要理解题意(甚至理解了反而可能会想偏),可以直接照题干按部就班dp(逃
在每一次输入操作后求出这个串正向和反向的哈希值,如果相等就是回文串,然后进行dp即可。
代码:
#include<iostream>
#include<cstdio>
using namespace std;
int ans,w=1,Lhash,Rhash,F[5000010],n;
const int seed=100007;
char ch;
int main(){
while((ch=getchar())!='\n'){
n++;
Lhash=Lhash+(ch-96)*w;
Rhash=Rhash*seed+(ch-96);
w*=seed;
if(Lhash==Rhash) F[n]=F[n>>1]+1;
ans+=F[n];
}
cout<<ans<<endl;
return 0;
}