人都要调麻了(悲
自认为码风还过得去
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
using namespace std;
const int MAXN = 1000005;
LL ans;
char str[MAXN];
class Graph {
private :
struct edge {
int to, nex;
}e[MAXN]; int idx;
public :
int head[MAXN];
inline void add(int u, int v) {
e[++ idx].to = v;
e[idx].nex = head[u];
head[u] = idx;
}
inline edge operator [] (const int x) const {
return e[x];
}
}G;
namespace SAM {
int idx, lst;
struct node {
int fath, sons[26];
int len, cnt;
}tr[MAXN << 1];
inline void nwNode(int length) {
tr[++ idx].len = length;
tr[idx].cnt = 1;
tr[idx].fath = -1;
memset(tr[idx].sons, 0, sizeof(tr[idx].sons));
}
inline void Init() {
idx = -1, lst = 0;
nwNode(0);
}
inline void Insert(int c) {
nwNode(tr[lst].len + 1);
int p = lst, cur = idx;
while (p != -1 && !tr[p].sons[c])
tr[p].sons[c] = cur, p = tr[p].fath;
if (p == -1)
tr[cur].fath = 0;
else {
int q = tr[p].sons[c];
if (tr[q].len == tr[p].len + 1)
tr[cur].fath = q;
else {
nwNode(tr[p].len + 1);
int nq = idx;
memcpy(tr[nq].sons, tr[q].sons, sizeof(tr[q].sons));
tr[nq].fath = tr[q].fath;
tr[cur].fath = tr[q].fath = nq;
while (p != -1 && tr[p].sons[c] == q)
tr[p].sons[c] = nq, p = tr[p].fath;
}
}
lst = cur;
}
inline void Build(char s[]) {
Init();
int length = strlen(s);
for (int i = 0; i < length; ++ i)
Insert(s[i] - 'a');
}
inline void dfs (int u) {
for (int i = G.head[u]; i; i = G[i].nex) {
int v = G[i].to;
dfs(v);
tr[u].cnt += tr[v].cnt;
}
if (tr[u].cnt != 1)
ans = max(ans, 1ll * tr[u].len * tr[u].cnt);
}
inline void Get_cnt() {
for (int i = 1; i <= idx; ++ i)
G.add(tr[i].fath, i);
dfs(0);
}
}
int main()
{
scanf ("%s", str);
SAM::Build(str);
SAM::Get_cnt();
return printf ("%lld\n", ans), 0;
}