您的位置:首页 > 其它

[51nod 1129] 字符串最大值(kmp)

2017-08-13 19:19 225 查看

传送门

题目大意

求一个字符串的前

缀出现次数乘以长度的最大值。

题解

暴力枚举每一个前缀求出现次数再乘以常数取最大 这样做会T几个点

看了老师的做法是任意前缀出现的次数,它的next也会出现这些次数

代码

暴力

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char s[1000009];
int nex[1000009],len;
long long max_ans;
void getnext(){
for(int i=2,j=0;i<=len;i++){//从2开始啊,扎心了老铁
while(s[i]!=s[j+1]&&j)j=nex[j];
if(s[i]==s[j+1])nex[i]=++j;
}
}
void slove(int k){
int js=0;
for(int i=1,j=0;i<=len;i++){
while(s[i]!=s[j+1]&&j)j=nex[j];
if(s[i]==s[j+1])++j;
if(j==k){
js++;j=nex[j];
}
}
//    cout<<k<<" "<<js<<" "<<js*k<<endl;
max_ans=max(max_ans,(long long)js*k);
}
int main(){
ios::sync_with_stdio(0);
freopen("string_maxval.in","r",stdin);
freopen("string_maxval.out","w",stdout);
scanf("%s",s+1);
len=strlen(s+1);
getnext();
for(int i=1;i<=len;i++)slove(i);
printf("%lld\n",max_ans);
return 0;
}

第二种方法

#include<cstdio>
#include<iostream>
#include<cstring>

using namespace std;
const int maxl=1000010;
char s[maxl],su[maxl];
int next[maxl],l,ans=0,cs[maxl];
void getnext()
{
next[0]=-1;
l=strlen(s);
for(int j,i=1;i<l;i++)
{
j=next[i-1];
while(s[i]!=s[j+1]&&j>=0)j=next[j];
next[i]=s[i]==s[j+1]?j+1:-1;
}
}
int main()
{
freopen("string_maxval.in","r",stdin);
freopen("string_maxval.out","w",stdout);
scanf("%s",s);
getnext();
for(int i=l-1;i>=0;--i)
{
cs[i]++;
cs[next[i]]+=cs[i];
if(cs[i]*(i+1)>ans)ans=cs[i]*(i+1);
}
cout<<ans;
fclose(stdin);fclose(stdout);
return 0;
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: