http://acm.hdu.edu.cn/showproblem.php?pid=6740
kmp水题,由于是a*已出现长度-b*循环节长度,所以说循环节越小越好,那么联想到kmp求nxt数组的时候可以知道当前长度i的最小循环节是i-nxt[i],所以直接把小数点后面的数字反过来,然后求一遍nxt数组,边求边记录最大值。
由于kmp的nxt数组是从第二位开始向本身匹配的,所以ans的初值赋值为a-b,即最后一位,它自己本身是循环节的情况。
#include<bits/stdc++.h>
#define maxl 10000010
using namespace std;
const long long inf=1ll<<61;
long long a,b,ans;
int slen,tlen;
int nxt[maxl];
char s[maxl],t[maxl];
inline void prework()
{
scanf("%s",s+1);
slen=strlen(s+1);tlen=0;
for(int i=slen;i>=1;i--)
if(s[i]=='.')
break;
else
t[++tlen]=s[i];
}
inline void mainwork()
{
ans=a-b;
int j=0;nxt[1]=0;
for(int i=2;i<=tlen;i++)
{
while((j && t[j+1]!=t[i]) || (j==tlen))
j=nxt[j];
if(t[j+1]==t[i] && j+1<=tlen)
j++;
nxt[i]=j;ans=max(ans,a*i-b*(i-nxt[i]));
}
}
inline void print()
{
printf("%lld\n",ans);
}
int main()
{
while(~scanf("%lld%lld",&a,&b))
{
prework();
mainwork();
print();
}
return 0;
}