1. 程式人生 > >[jzoj 5178] [NOIP2017提高組模擬6.28] So many prefix? 解題報告(KMP+DP)

[jzoj 5178] [NOIP2017提高組模擬6.28] So many prefix? 解題報告(KMP+DP)

題目連結:

https://jzoj.net/senior/#main/show/5178

題目:

題解:

我們定義$f[pos]$表示以位置pos為字尾的字串對答案的貢獻,答案就是$\sum_{i=1}^{n} f[i]$

考慮怎麼得到f陣列,我們有$f[i]=f[nxt[i]]+[i是偶數]$

其實蠻顯然的,$f[i]$和$f[nxt[i]]$除了多出字首i這個貢獻沒什麼區別

#include<algorithm>
#include<cstring>
#include<cstdio>
#include<iostream>
using
namespace std; typedef long long ll; const int N=2e5+15; char ch[N]; int nxt[N],f[N]; int main() { scanf("%s",ch+1); nxt[1]=0; int n=strlen(ch+1); for (int i=2,j=0;i<=n;i++) { while (j&&ch[j+1]!=ch[i]) j=nxt[j]; if (ch[j+1]==ch[i]) ++j; nxt[i]
=j; } for (int i=1;i<=n;i++) { if (!(i&1)) f[i]=f[nxt[i]]+1; else f[i]=f[nxt[i]]; } ll ans=0; for (int i=1;i<=n;i++) ans+=f[i]; printf("%d\n",ans); return 0; }