题目:
思路:倒着跑kmp,然后枚举循环起点,求循环节。代入方程求最大值。
#include <bits/stdc++.h>
#define LL long long
using namespace std;
char s[10000010];
int f[10000010];
void get_next(int n){
int i=0, j=-1;
f[0]=-1;
while(i<n){
if(j==-1||s[i]==s[j]){
i++, j++, f[i]=j;
}
else{
j=f[j];
}
}
}
int main()
{
LL a, b, tot=-1;
scanf("%lld%lld%*c", &a, &b);
char c;
while(scanf("%c", &c), c!='\n'){
if(tot!=-1){
s[tot++]=c;
}
if(c=='.'){
tot=0;
}
}
int L=0, R=tot-1;
while(L<=R){
swap(s[L], s[R]);
L++, R--;
}
get_next(tot);
LL MIN=-1e18;
for(int i=0; i<tot; i++){
MIN=max(MIN, a*(i+1)-b*(i+1-f[i+1]));
}
printf("%lld\n", MIN);
return 0;
}
HDU 6740
#include <bits/stdc++.h>
#define LL long long
using namespace std;
char c[10000010];
char s[10000010];
LL f[10000010];
void get_next(LL n){
LL i=0, j=-1;
f[0]=-1;
while(i<n){
if(j==-1||s[i]==s[j]){
i++, j++, f[i]=j;
}
else{
j=f[j];
}
}
}
int main()
{
LL a, b, tot=-1;
while(scanf("%lld%lld%s", &a, &b, c)!=EOF){
tot=-1;
int n=strlen(c);
for(int i=n-1; i>=0&&c[i]!='.'; i--){
s[++tot]=c[i];
}
s[++tot]=0;
get_next(tot);
LL MIN=-1e18;
for(LL i=0; i<tot; i++){
MIN=max(MIN, a*(i+1)-b*(i+1-f[i+1]));
}
printf("%lld\n", MIN);
}
return 0;
}