J - MUV LUV EXTRA(KMP)

感受
思 路 很 简 单 , 就 是 不 知 道 k m p 还 可 以 求 最 小 循 环 节 长 度 思路很简单,就是不知道kmp还可以求最小循环节长度 kmp
思路
显 然 , 我 们 需 要 枚 举 p 即 后 缀 n 、 后 缀 n − 1 、 . . . 显然,我们需要枚举p即后缀n、后缀n-1、... pnn1...
对 于 每 一 个 后 缀 , 我 们 需 要 找 到 最 小 的 l 即 最 小 循 环 节 长 度 对于每一个后缀,我们需要找到最小的l即最小循环节长度 l
通 过 这 样 , 可 以 最 大 化 a ∗ p − b ∗ l 通过这样,可以最大化a*p-b*l apbl
问 题 转 化 : 如 何 求 出 一 个 串 的 最 小 循 环 节 长 度 ? 问题转化:如何求出一个串的最小循环节长度? :
a n s = 串 长 度 − 串 前 缀 与 后 缀 的 最 长 公 共 部 分 ( n e x t 数 组 ) ans=串长度-串前缀与后缀的最长公共部分(next数组) ans=(next)
结 论 不 太 会 证 明 , 直 接 记 住 应 该 也 可 。 结论不太会证明,直接记住应该也可。

#include <bits/stdc++.h>
#define next NEXT
using namespace std;
typedef long long ll;
const int maxn = 1e7 + 10;
int next[maxn], n, m;
char s[maxn], t[maxn];
ll a, b;
void initkmp(char x[], int m){
 int i = 0, j = next[0] = -1;
 while(i < m){
  while(j != -1 && x[i] != x[j]) j = next[j];
  next[++i] = ++j;
 }
}
int main(){
 scanf("%lld%lld", &a, &b);
 scanf("%s", s + 1);
 n = strlen(s + 1);
 for(int i = n; i >= 1; i--){
  if(s[i] == '.') break;
  t[m++] = s[i];
 }
 initkmp(t, m);
 bool ok = false; ll ans;
 for(int i = 1; i <= m; i++){
  if(!ok) ans = a * i - b * (i - next[i]), ok = true;
  else ans = max(ans, a * i - b * (i - next[i]));
 }
 printf("%lld\n", ans);
 return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值