51Nod 1277 - 字符串中的最大值(KMP)

【题目描述】
在这里插入图片描述

【思路】
假设现在有一个位置 pospos ,其前缀已经出现一次即 [0,pos1][0,pos-1] 这个前缀已经出现了一次,现在考虑一下 next[pos]next[pos] 的意义,其实就是包含在 [0,pos1][0,pos-1] 这个前缀里面的前缀(前缀针对整个字符串而言,并非 [0,pos1][0,pos-1] 这个子串),也就是如果我们能够知道一个前缀出现的次数,那么包含在这个前缀里面的前缀也应当又出现了一次,所以只要跑一遍 KMP 得到 nextnext 数组,然后对每一个前缀出现的次数都叠加到其包含的前缀当中去,即状态转移方程 dp[next[i]]+=dp[i]dp[next[i]] += dp[i] ( d[i]d[i] 代表长度为 ii 的前缀出现的次数),整个过程应该是逆推的

#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;
}
posted @ 2018-11-07 21:45  不想吃WA的咸鱼  阅读(221)  评论(0)    收藏  举报