#include <set>
#include <cstdio>
#include <cstring>
using namespace std;
struct E
{
int v, t;
} e[2000050];
char a[2000050];
int n, k, o, z, w, _, Z, l[2000050], p[2000050], b[2000050], _b[2000050], d[2000050], s[2000050], h[2000050], P[2000050], S[2000050], f[2000050], c[2000050][26];
void A(int u, int v) { e[++_] = {v, h[u]}, h[u] = _; }
void I(int x)
{
int u = ++o, p = z;
l[u] = l[z] + 1;
while (p != -1 && !c[p][x])
c[p][x] = u, p = f[p];
if (p == -1)
f[u] = 0;
else
{
int q = c[p][x];
if (l[p] + 1 == l[q])
f[u] = q;
else
{
int w = ++o;
l[w] = l[p] + 1;
f[w] = f[q];
for (int i = 0; i < 26; ++i)
c[w][i] = c[q][i];
while (p != -1 && c[p][x] == q)
c[p][x] = w, p = f[p];
f[q] = f[u] = w;
}
}
z = u;
}
void X(int u)
{
_b[b[u] = ++w] = u, s[u] = 1, p[u] = -1;
for (int i = h[u], v; i; i = e[i].t)
{
d[v = e[i].v] = d[u] + 1;
X(v), s[u] += s[v];
if (p[u] == -1 || s[v] > s[p[u]])
p[u] = v;
}
}
int W(int x, int y, int o)
{
if (o < y - x)
return 0;
int _ = o / (y - x) + 1;
return (_ / k) * (y - x) * k;
}
struct BIT
{
int O, _, a[2000050], c[2000050];
void M(int x, int k)
{
O += k, a[x] += k;
for (; x <= n; x += x & -x)
c[x] += k;
}
int Q(int x)
{
int q = 1;
for (--x; x; x &= x - 1)
q += c[x];
return _ = q;
}
int K(int k)
{
int z = 0, s = 0;
for (int i = 20; i >= 0; --i)
if (z + (1 << i) <= n && s + c[z + (1 << i)] < k)
s += c[z += 1 << i];
return z + 1;
}
int P(int x)
{
int o = Q(x);
return o == 1 ? 0 : K(o - 1);
}
int N(int x)
{
int o = _ + 1;
return o == n + 1 ? n + 1 : K(o);
}
} EP;
void Q(int u, int o)
{
for (int i = h[u], v; i; i = e[i].t)
if ((v = e[i].v) != p[u])
Q(v, 0);
if (p[u] != -1)
Q(p[u], 1);
if (P[u] && !EP.a[P[u]])
{
EP.M(P[u], 1);
int pr = EP.P(P[u]), nx = EP.N(P[u]);
if (pr != 0)
Z = max(Z, W(pr, P[u], l[u]));
if (nx != n + 1)
Z = max(Z, W(P[u], nx, l[u]));
}
for (int i = h[u], v; i; i = e[i].t)
if ((v = e[i].v) != p[u])
{
for (int j = b[v]; j < b[v] + s[v]; ++j)
if (P[_b[j]] && !EP.a[P[_b[j]]])
{
EP.M(P[_b[j]], 1);
int pr = EP.P(P[_b[j]]), nx = EP.N(P[_b[j]]);
if (pr != 0)
Z = max(Z, W(pr, P[_b[j]], l[u]));
if (nx != n + 1)
Z = max(Z, W(P[_b[j]], nx, l[u]));
}
}
if (!o)
{
for (int i = b[u]; i < b[u] + s[u]; ++i)
if (P[_b[i]] && EP.a[P[_b[i]]])
EP.M(P[_b[i]], -1);
}
}
int main()
{
memset(f, -1, sizeof f);
scanf("%d%d%s", &n, &k, a + 1);
for (int i = 1; i <= n; ++i)
I(a[i] - 'a');
for (int i = 1; i <= o; ++i)
A(f[i], i);
X(0);
for (int i = 1; i <= n; ++i)
P[S[i] = c[S[i - 1]][a[i] - 'a']] = i;
Q(0, 1);
printf("%d", Z);
return 0;
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
2024-02-22 周期