[CEOI2017]Palindromic Partitions

[CEOI2017]Palindromic Partitions

题目大意:

给出一个长度为\(n(n\le10^6)\)的只包含小写字母字符串,要求你将它划分成尽可能多的小块,使得这些小块构成回文串。

思路:

哈希以后从两侧往里贪心,尽量取短的。

时间复杂度\(\mathcal O(n)\)

源代码:

#include<cstdio>
#include<cctype>
#include<cstring>
inline int getint() {
	register char ch;
	while(!isdigit(ch=getchar()));
	register int x=ch^'0';
	while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
	return x;
}
typedef unsigned long long uint64;
const int N=1e6+2;
const uint64 base=33;
char s[N];
uint64 pwr[N],hash[N];
inline uint64 calc(const int &l,const int &r) {
	return hash[r]-hash[l-1]*pwr[r-l+1];
}
int main() {
	for(register int T=getint();T;T--) {
		scanf("%s",&s[1]);
		const int n=strlen(&s[1]);
		for(register int i=pwr[0]=1;i<=n;i++) {
			pwr[i]=pwr[i-1]*base;
			hash[i]=hash[i-1]*base+s[i]-'a';
		}
		int last=0,ans=0;
		for(register int i=1;i<=n/2;i++) {
			if(calc(last+1,i)==calc(n-i+1,n-last)) {
				last=i;
				ans+=2;
			}
		}
		if(last*2<n) ans++;
		printf("%d\n",ans);
	}
	return 0;
}
posted @ 2018-09-21 14:53  skylee03  阅读(301)  评论(0编辑  收藏  举报