时间限制: 1 Sec 内存限制: 128 MB
题目描述
Let s be a given string of up to 106 digits. Find the maximal k for which it is possible to partition s into k consecutive contiguous substrings, such that the k parts form a palindrome.
More precisely, we say that strings s0, s1, . . . , sk−1 form a palindrome if si = sk−1−i for all 0 ≤ i < k.
In the first sample case, we can split the string 652526 into 4 parts as 6|52|52|6, and these parts together form a palindrome. It turns out that it is impossible to split this input into more than 4 parts while still making sure the parts form a palindrome.
输入
A nonempty string of up to 106 digits.
输出
Print the maximal value of k on a single line.
样例输入
652526
样例输出
4
字符串哈希裸题,O(n)
#pragma GCC optimize(3,"Ofast","inline")
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <queue>
#include <vector>
#include <map>
#include <cmath>
#include <stack>
#include <set>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 1010;
const int MAXN = 1000010;
const int Hash = 13131;
const int mod =1e9+7;
ull base[MAXN],h[MAXN];
char str[MAXN];
void init(int n){
base[0]=1;
h[0]=Hash;
for(int i=1;i<=n;i++){
base[i]=base[i-1]*Hash;
h[i]=h[i-1]*Hash+str[i];
}
}
bool check(int l,int r,int len){
//cout<<"checkl "<<l<<" "<<len<<" "<<h[l]-h[l-len]*base[len]<<endl;
//cout<<"checkr "<<r<<" "<<len<<" "<<h[r+len-1]-h[r-1]*base[len]<<endl;
return h[l]-h[l-len]*base[len]==h[r+len-1]-h[r-1]*base[len];
}
int main()
{
scanf("%s",str+1);
int len=strlen(str+1);
// cout<<len<<endl;
init(len);
int ans=0;
int anslen=0;
for(int i=1,j=len;i<=(len>>1)&&j>=(len>>1);i++,j--){
//cout<<i<<" "<<anslen<<endl;
anslen++;
if(check(i,j,anslen)){
ans++;
anslen=0;
}
}
ans<<=1;
//if(anslen==0)
//
// ans+=len&1;
if(len&1){
ans++;
}else{
if(anslen!=0)
ans++;
}
cout<<ans<<endl;
return 0;
}