广义后缀自动机(在线)
#include "../header.cpp"
namespace SAM{
int M[MAXN][MAXM], L[MAXN], F[MAXN], S[MAXN], s = 0, h = 25;
void init(){
F[0] = -1, s = 0;
}
// 每次插入新字符串前将 last 清零
void extend(int &last, char c){
int e = c - 'a';
if(M[last][e]){
int p = last;
int q = M[last][e];
if(L[q] == L[last] + 1){
last = q;
} else {
int clone = ++ s;
L[clone] = L[p] + 1, F[clone] = F[q];
for(int i = 0;i <= h;++ i)
M[clone][i] = M[q][i];
while(p != -1 && M[p][e] == q)
M[p][e] = clone, p = F[p];
F[q] = clone;
last = clone;
}
} else {
int cur = ++ s;
L[cur] = L[last] + 1;
int p = last;
while(p != -1 && !M[p][e])
M[p][e] = cur, p = F[p];
if(p == -1){
F[cur] = 0;
} else {
int q = M[p][e];
if(L[p] + 1 == L[q]){
F[cur] = q;
} else {
int clone = ++ s;
L[clone] = L[p] + 1,F[clone] = F[q];
for(int i = 0;i <= h;++ i)
M[clone][i] = M[q][i];
while(p != -1 && M[p][e] == q)
M[p][e] = clone, p = F[p];
F[cur] = F[q] = clone;
}
}
last = cur;
}
}
}