(⊙o⊙)…也许会咕咕咕……
SAM
#include <bits/stdc++.h>
using namespace std;
int const N = 1e6 * 4;
char s[1000001];
struct SuffixAutomation
{
int siz, lst, tot;
long long ans = -1;
int h[N], size[N];
struct edge
{
int to, next;
} e[N];
struct state
{
int link, len;
int next[50];
} st[N];
void init()
{
st[siz].len = 0, st[siz].link = -1;
lst = 0;
}
void add(int u, int v)
{
e[++tot].to = v, e[tot].next = h[u], h[u] = tot;
}
void insert(int c)
{
int np = ++siz, p = lst;
st[np].len = st[lst].len + 1;
size[np] = 1;
for (; p != -1 && !st[p].next[c]; p = st[p].link)
st[p].next[c] = np;
if (p == -1)
{
st[np].link = 0;
}
else
{
int q = st[p].next[c];
if (st[q].len == st[p].len + 1)
{
st[np].link = q;
}
else
{
int clone = ++siz;
st[clone] = st[q];
st[clone].len = st[p].len + 1;
st[np].link = st[q].link = clone;
while (p != -1 && st[p].next[c] == q)
{
st[p].next[c] = clone;
p = st[p].link;
}
}
}
lst = np;
}
void prework()
{
for (int i = 1; i <= siz; ++i)
{
add(st[i].link, i);
}
dfs(0);
}
void dfs(int x)
{
for (int i = h[x]; i; i = e[i].next)
{
dfs(e[i].to);
size[x] += size[e[i].to];
}
if (size[x] != 1)
ans = max((long long)size[x] * st[x].len, ans);
return;
}
} SAM;
int main()
{
scanf("%s", s);
int len = strlen(s);
SAM.init();
for (int i = 0; i < len; i++)
{
SAM.insert(s[i] - 'a');
}
SAM.prework();
printf("%lld
", SAM.ans);
return 0;
}