样例一
期望答案552,输出1092
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<map>
using namespace std;
const int N = 1e6+100;
int n, last, size, edge_cnt, head[N << 1];
char str[N];
struct SAM_state {
int len, link, cnt, next[26];
SAM_state(): len(0), link(-1), cnt(0) {
for(int i = 0; i < 26; i++)
next[i] = -1;
}
} st[N << 1];
struct Edge {
int to, next;
Edge(): next(-1) {}
} edge[N << 1];
void init() {
st[0].len = 0;
st[0].link = -1;
size++;
last = 0;
memset(head, -1, sizeof(head));
}
void sam_extend(char c) {
int cur = size++;
st[cur].cnt = 1;
st[cur].len = st[last].len + 1;
int p = last;
while(p != -1 && st[p].next[c - 'a'] == -1) {
st[p].next[c - 'a'] = cur;
p = st[p].link;
}
if(p == -1) {
st[cur].link = 0;
} else {
int q = st[p].next[c - 'a'];
if(st[p].len + 1 == st[q].len) {
st[cur].link = q;
} else {
int clone = size++;
st[clone] = st[q];
st[clone].len = st[p].len + 1;
while(p != -1 && st[p].next[c - 'a'] == q) {
st[p].next[c - 'a'] = clone;
p = st[p].link;
}
st[cur].link = clone;
st[q].link = clone;
}
}
last = cur;
}
void add_edge(int from, int to) {
edge_cnt++;
edge[edge_cnt].to = to;
edge[edge_cnt].next = head[from];
head[from] = edge_cnt;
}
int dfs(int k) {
for(int i = head[k]; i != -1; i = edge[i].next)
st[k].cnt += dfs(edge[i].to);
return st[k].cnt;
}
int main() {
scanf("%s", str + 1);
n = strlen(str + 1);
init();
for(int i = 1; i <= n; i++)
sam_extend(str[i]);
for(int i = 0; i < size; i++)
if(st[i].link != -1)
add_edge(st[i].link, i);
dfs(0);
int ans = 0;
for(int i = 1; i < size; i++)
if(st[i].cnt > 1 && st[i].cnt * st[i].len > ans)
ans = st[i].cnt * st[i].len;
printf("%d\n", ans);
return 0;
}