51Nod 1277 - 字串中的最大值(KMP)
阿新 • • 發佈:2018-11-08
【題目描述】
【思路】
假設現在有一個位置
,其字首已經出現一次即
這個字首已經出現了一次,現在考慮一下
的意義,其實就是包含在
這個字首裡面的字首(字首針對整個字串而言,並非
這個子串),也就是如果我們能夠知道一個前綴出現的次數,那麼包含在這個字首裡面的字首也應當又出現了一次,所以只要跑一遍 KMP 得到
陣列,然後對每一個前綴出現的次數都疊加到其包含的字首當中去,即狀態轉移方程
(
代表長度為
的前綴出現的次數),整個過程應該是逆推的
#include<bits/stdc++.h>
using namespace std;
const int maxn=100005;
char p[maxn];
int nxt[maxn],lenp;
long long dp[maxn];
void getnext(){
nxt[0]=-1;
int j=0,k=-1;
while(j<lenp){
if(k==-1 || p[k]==p[j]){
++j;
++k;
nxt[j]=k;
}
else k=nxt[k];
}
}
int main(){
scanf("%s",p);
lenp=strlen(p);
getnext();
for(int i=1;i<=lenp;++i) dp[i]=1;
for(int i=lenp;i>=1;--i) dp[nxt[i]]+=dp[i];
long long ans=0;
for(int i=1;i<=lenp;++i) ans=max(ans,(long long)i*dp[i]);
printf("%lld\n",ans);
return 0;
}