普通后缀自动机模板
struct node { int len, link, sz; map<char, int> next; } sam[2000010];
int tot, last;
void init() { tot = 1, last = 1; sam[1].len = 0, sam[1].link = -1, sam[1].sz = 1, sam[1].next.clear(); }
void insert(char ch)
{
int cur = ++tot, p = last; sam[cur].len = sam[last].len + 1, sam[cur].sz = 1, sam[cur].next.clear();
while (p != -1 && sam[p].next.count(ch) == false) sam[p].next[ch] = cur, p = sam[p].link;
if (p == -1) sam[cur].link = 1;
else
{
int q = sam[p].next[ch];
if (sam[p].len + 1 == sam[q].len) sam[cur].link = q;
else
{
int cjh = ++tot; sam[cjh].len = sam[p].len + 1, sam[cjh].link = sam[q].link, sam[cjh].next = sam[q].next;
while (p != -1 && sam[p].next[ch] == q) sam[p].next[ch] = cjh, p = sam[p].link;
sam[q].link = sam[cur].link = cjh;
}
}
last = cur;
}