1. 程式人生 > >hihocoder 1445 : 字尾自動機二·重複旋律5(字尾自動機)

hihocoder 1445 : 字尾自動機二·重複旋律5(字尾自動機)

給入門新手的模板題,套kuangbin大佬的模板。
當前節點的minlen就等於當前節點的fa節點的maxlen+1。

#include <bits/stdc++.h>
using namespace std;
const int CHAR = 26;
const int MAXN = 1100010;
long long res = 0;
struct SAM_Node
{
    SAM_Node *fa,*next[CHAR];
    int len;
    int id,pos;
    SAM_Node() {}
    SAM_Node(int _len)
    {
        fa = 0
; len = _len; memset(next,0,sizeof(next)); } }; SAM_Node SAM_node[MAXN*2], *SAM_root, *SAM_last; int SAM_size; SAM_Node *newSAM_Node(int len) { SAM_node[SAM_size] = SAM_Node(len); SAM_node[SAM_size].id = SAM_size; return &SAM_node[SAM_size++]; } SAM_Node *newSAM_Node
(SAM_Node *p) { SAM_node[SAM_size] = *p; SAM_node[SAM_size].id = SAM_size; return &SAM_node[SAM_size++]; } void SAM_init() { SAM_size = 0; SAM_root = SAM_last = newSAM_Node(0); SAM_node[0].pos = 0; } void SAM_add(int x,int len) { SAM_Node *p = SAM_last, *np = newSAM_Node(p->len+1
); np->pos = len; SAM_last = np; for(; p && !p->next[x]; p = p->fa) p->next[x] = np; if(!p) { np->fa = SAM_root; res += (np->len-np->fa->len); return; } SAM_Node *q = p->next[x]; if(q->len == p->len + 1) { np->fa = q; res += (np->len-np->fa->len); return; } SAM_Node *nq = newSAM_Node(q); nq->len = p->len + 1; q->fa = nq; np->fa = nq; for(; p && p->next[x] == q; p = p->fa) p->next[x] = nq; res += (np->len-np->fa->len); } void SAM_build(char *s) { SAM_init(); int len = strlen(s); for(int i = 0; i < len; i++) SAM_add(s[i] - 'a',i+1); } char str[MAXN]; int main() { scanf("%s",str); SAM_build(str); printf("%lld\n",res); return 0; }