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...