sd2

#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;
}
posted @   Jijidawang  阅读(41)  评论(3编辑  收藏  举报
相关博文:
阅读排行:
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
历史上的今天:
2024-02-22 周期
点击右上角即可分享
微信分享提示