【模板】广义后缀自动机模板

建立在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;
}

猜你喜欢

转载自www.cnblogs.com/dream-maker-yk/p/9710625.html
今日推荐