[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;
}

转载于:https://www.cnblogs.com/skylee03/p/9686537.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值