Codeforces Round #463 (Div. 1 + Div. 2, combined) G:Palindrome Partition(回文自动机)

Codeforces Round #463 - 回文自动机解析
本文介绍了Codeforces Round #463的一道难题,探讨了如何利用回文串的回文后缀特性解决该问题,该特性涉及等差数列。建议参考官方题解以获取详细解答。

传送门

题解:
这是一道神题,具体题解直接看官方的比较好
用到了策爷字符串ppt中回文串的回文后缀是 logn log ⁡ n 个等差数列的性质。

#include <bits/stdc++.h>
using namespace std;
const int N=1e6+50;
const int mod=1e9+7;
int n,f[N],tot=1;
char s[N],t[N];
int last,son[N][27],diff[N],len[N],link[N],slink[N],series_ans[N];
inline int getfail(int pos,int l) {
    while(s[l-len[pos]-1]!=s[l]) pos=link[pos];
    return pos;
}
int main() {
    len[1]=-1; link[0]=1; diff[0]=1;
    scanf("%s",t+1); n=strlen(t+1);
    if(n&1) {puts("0"); return 0;}
    for(int i=1;i<=n;i++) {
        if(i&1) s[i]=t[(i+1)/2];
        else s[i]=t[n-i/2+1];
    }
    f[0]=1;
    for(int i=1;i<=n;i++) {
        int c=s[i]-'a'+1;
        int now=getfail(last,i);
        if(!son[now][c]) {
            len[++tot]=len[now]+2;
            link[tot]=son[getfail(link[now],i)][c];
            diff[tot]=len[tot]-len[link[tot]];
            if(diff[tot]==diff[link[tot]]) slink[tot]=slink[link[tot]];
            else slink[tot]=link[tot];
            son[now][c]=tot;
        } last=son[now][c];
        for(int v=last;len[v];v=slink[v]) {
            series_ans[v]=f[i-(len[slink[v]]+diff[v])];
            if(diff[v]==diff[link[v]])
                series_ans[v]=(series_ans[v]+series_ans[link[v]])%mod;
            f[i]=(f[i]+series_ans[v])%mod;
        }
        if(i&1) f[i]=0;
    }
    printf("%d\n",f[n]);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值