主要是好几个双倍经验都过了 就这题Wa了一个点, 难蚌
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int INF = (int)1e9;
const int N = 1e6 + 10;
int n, len;
char s[15][N];
struct Sam{
struct Node{
int len, link, cnt, mini;
map <char, int> nxt;
}st[N];
int cnt, lst;
int mx[N];
void Init(){
st[0].len = 0;
st[0].link = -1;
lst = 0;
}
void Insert(char c){
int p = lst, cur = ++cnt;
st[cur].len = st[lst].len + 1;
st[cur].cnt = 1;
st[cur].mini = st[cur].len;
while(p != -1 && !st[p].nxt[c]){
st[p].nxt[c] = cur;
p = st[p].link;
}
if(p == -1){
st[cur].link = 0;
}else{
int q = st[p].nxt[c];
if(st[q].len == st[p].len + 1){
st[cur].link = q;
}else{
int clone = ++cnt;
st[clone].cnt = 0;
st[clone].len = st[p].len + 1;
st[clone].nxt = st[q].nxt;
st[clone].link = st[q].link;
st[clone].mini = st[clone].len;
while(p != -1 && st[p].nxt[c] == q){
st[p].nxt[c] = clone;
p = st[p].link;
}
st[q].link = st[cur].link = clone;
}
}
lst = cur;
}
void Print(){
for(int i = 0; i <= cnt; i++){
cout << i << "i ";
cout << st[i].len << "len ";
cout << st[i].link << "link ";
for(auto j : st[i].nxt){
cout << j.first << "+" << j.second << " ";
}
cout << "nxt\n";
}
}
void Ans(char *s){
int p = 0, len = 0;
int ed = strlen(s + 1);
for(int i = 1; i <= ed; i++){
if(st[p].nxt[s[i]]){
len++;
p = st[p].nxt[s[i]];
mx[p] = max(mx[p], len);
}else{
while(p != -1 && !st[p].nxt[s[i]]){
p = st[p].link;
}
if(p == -1){
len = 0, p = 0;
}else{
len = st[p].len + 1;
p = st[p].nxt[s[i]];
mx[p] = max(mx[p], len);
}
}
// cout << len << "+" << p << " ";
}
// cout << "len\n";
for(int i = cnt; i >= 1; i--){
mx[st[i].link] = max(mx[st[i].link], min(st[st[i].link].len, mx[i]));
st[i].mini = min({st[i].mini, mx[i]});
mx[i] = 0;
// cout << st[i].mini << " ";
}
// cout << "\n";
}
int Get_ans(){
int maxlen = 0;
for(int i = 1; i <= cnt; i++){
maxlen = max(maxlen, st[i].mini);
// cout << st[i].mini << " ";
}
// cout << "\n";
return maxlen;
}
}sam;
signed main(){
freopen("1.in", "r", stdin);
int minsi = INF, id = 0;
cin >> n;
for(int i = 1; i <= n; i++){
cin >> (s[i] + 1);
if((int)strlen(s[i] + 1) < minsi){
minsi = (int)strlen(s[i] + 1);
id = i;
}
}
swap(s[1], s[id]);
sam.Init();
len = strlen(s[1] + 1);
for(int i = 1; i <= len; i++){
sam.Insert(s[1][i]);
}
// sam.Print();
// cout << n << "\n";
for(int i = 1; i <= n; i++){
sam.Ans(s[i]);
}
cout << sam.Get_ans() << "\n";
}