【模板】广义后缀自动机模板
建立在tire上的广义后缀自动机,采用bfs的建图方式,可以保证复杂度
#include<bits/stdc++.h>
using namespace std;
#define fu(a,b,c) for(int a=b;a<=c;++a)
#define fd(a,b,c) for(int a=b;a>=c;--a)
#define MAXN 2000010
#define LL long long
const int CHARSET_SIZE=10;
//Suffix_Automaton
struct Sam{
Sam *ch[CHARSET_SIZE],*prt;
int maxl;
Sam(int maxl=0):maxl(maxl){}
};
struct Suffix_Automaton{
Sam pool[MAXN<<1],*cur,*root;
Suffix_Automaton(){
cur=pool;
root=new (cur++)Sam;
}
Sam *extend(int c,Sam *last){
Sam *u=new (cur++)Sam(last->maxl+1),*v=last;
for(;v&&!v->ch[c];v=v->prt)v->ch[c]=u;
if(!v)u->prt=root;
else if(v->ch[c]->maxl==v->maxl+1){
u->prt=v->ch[c];
}else{
Sam *n=new (cur++)Sam(v->maxl+1),*o=v->ch[c];
copy(o->ch,o->ch+CHARSET_SIZE,n->ch);
n->prt=o->prt;
o->prt=u->prt=n;
for(;v&&v->ch[c]==o;v=v->prt)v->ch[c]=n;
}
return u;
}
LL solve(){
LL ans=0;
for(Sam *p=pool+1;p!=cur;p++)
ans+=p->maxl-p->prt->maxl;
return ans;
}
}sam;
//Trie
struct Node{Node *ch[CHARSET_SIZE];};
struct Trie{
Node pool[MAXN],*cur,*root;
Trie(){cur=pool;}
Node *insert(Node *last,int c){
if(!last->ch[c])last->ch[c]=new (cur++)Node;
return last->ch[c];
}
#define pi pair<Node*,Sam*>
void bfs(){
queue<pi> q;
q.push(pi(root,sam.root));
while(!q.empty()){
pi u=q.front();q.pop();
fu(i,0,9)
if(u.first->ch[i]){
Sam *tmp=sam.extend(i,u.second);
q.push(pi(u.first->ch[i],tmp));
}
}
}
}trie;
int main(){
return 0;
}