版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_41603898/article/details/101637516
枚举循环节已出现的长度 p,最优的循环节就是最后 p 个字
符构成的字符串的最短周期。
考虑把字符串倒过来,使用 kmp 可以求出每个前缀的最短
周期,即求出了原串每个后缀的最短周期。
#include<iostream>
#include<algorithm>
#include<string.h>
#include<string>
using namespace std;
const int N = 1e7 + 5;
typedef long long ll;
char s[N];
char s1[N];
int to[N];
void get_to() {
to[1] = 0;
int k = 0, n = strlen(s + 1);
for (int i = 2; i <= n; i++) {
while (k && s[i] != s[k + 1]) k = to[k];
if (s[i] == s[k + 1]) k++;
to[i] = k;
}
}
int main() {
ll a, b;
while (~scanf("%lld%lld", &a, &b)) {
scanf("%s", s1 + 1);
int n = strlen(s1 + 1);
int tot = 0;
for (int i = n; i > 0; i--) {
if (s1[i] == '.') break;
s[++tot] = s1[i];
}
s[++tot] = '\0';
//printf("%s\n", s + 1);
get_to();
n = strlen(s + 1);
ll cnt = -1e18;
for (int i = n; i; i--) {
ll tmp = to[i];
cnt = max(cnt, a * i - b * (i - tmp));
}
cout << cnt << endl;
}
return 0;
}