码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2018-09-27 00:06:57      阅读:161      评论:0      收藏:0      [点我收藏+]

标签:turn   using   for   while   后缀   space   names   mat   +=   

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

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

标签:turn   using   for   while   后缀   space   names   mat   +=   

原文地址:https://www.cnblogs.com/dream-maker-yk/p/9710625.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!