AC自動機及字尾自動機

2021-08-21 16:17:37 字數 2100 閱讀 8119

ac自動機是一種基於trie樹的演算法,其本質和kmp上的處理很相似。

trie樹結構:

kmp轉移思路:

ac自動機組要由三個部分組成:trie樹的建立  fail指標的匹配  對ac自動機的詢問

每次建立自動機會有一次初始化

ac自動機類

struct node    //node結構體

};struct ac

void init() //時間換空間

//void init() //空間換時間

node* newnode()

//int idx(char c) //size=128,可見字元在128以內

inline int idx(char c) //size=26

void insert(char *s,int num) //插入字串建樹

u->exist=num;

/*其他操作,在每次插入字串的結尾node上進行操作*/

}queueq; //fail指標的構建,採用bfs

void build()

q.push(u->next[i]);}}

}}

void query(char* s)

temp=temp->fail;}}

}}

void del(node* rt)

};ac ac;

struct node    //node結構體

};struct ac

void init()

inline int idx(char c) //size=26

void insert(char *s) //插入字串建樹

while(!q.empty())

else trie[u].next[i]=trie[trie[u].fail].next[i];//就是fail}}

}void query(char *s)

};ac ac;

在ac自動機上面進行dp,需要注意的事情:

1.由於構建fail的時候,下層的結點具有與其fail結點共有的性質,我們需要將fail節點的性質向下賦值。

#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#define maxn 1005

#define maxm 105

typedef long long ll;

const int inf=1e8+7;

ll mod=998244353;

const double eps=1e-9;

using namespace std;

inline void read(int &x)

inline void readll(ll &x)

int n;

mapmp;

char s[maxn];

ll f[maxn][maxn];

int size=4;

struct node //node結構體

};struct ac

void init()

inline int idx(char c) //size=26

void insert(char *s) //插入字串建樹

while(!q.empty())

else trie[u].next[i]=trie[trie[u].fail].next[i];//就是fail}}

}ll query(char *str)}}

}for(int i=0;iif(res==inf)res=-1;

return res;

}};ac ac;

int main()

ac.build();

scanf("%s",s);

printf("case %d: %lld\n",++cas,ac.query(s));

}return 0;

}

字尾自動機 序列自動機綜合

好像序列自動機還沒有寫過 串長為n的串共有n 1個節點,除了串中的n個節點,還有乙個空的根節點放在串首。每個節點至多有26條出邊,每條邊連向它之後的第乙個字元。串中的任意乙個子串行對應了一條根到某個節點的路徑。且每條路徑對應乙個不同的子串行。每個節點的parent是這個字母上一次出現的位置。更新只要...

AC自動機 建立nlogn個AC自動機

string set queries 題意 給你3種操作,1 加入乙個串到集合中。2 刪除集合中的某乙個串 3 查詢集合中的字串在給定的字串種出現幾次。同乙個串可重複 解法 建立多個ac自動機,用二進位制分組來處理。加入給你21個串 分為 16 4 1,再新增乙個串的時候,即21 1,22 16 4...

字尾自動機

基礎知識 step i 表示的是字串i在原字串中的位置。pareint i 表示root到parent i 的子串是root到i的最長字尾。字尾自動機遍歷可以得到原字串的所有子串。特殊技巧 一 字尾自動機的不同子串數有兩種求法 1.ans step i step parent i 1 i cnt 2...