POJ 2778 ac automata + Matrix fast Power////topic Link:////http://poj.org/problem?id=2778////Problem-solving ideas:////establish AC automata, determine the relationship between states, construct, go one step// Can reach the state matrix, and then the N-multiplication, you can get the state//walk n steps of the number of methods.//Essence://1): This AC automaton has some special, the root node is an empty string, however//every step of the time, if you can't go, when, not necessarily back to the root//node, Because there is the possibility of a single character when the virus, so that, not casually can reach//so-called root node, so each time the initialization, can not be 0, but should be//-1.////sentiment:////this way ac automata, start I was completely not, know is AC automata + Matrix fast power//start, Since the AC automatic mechanism made is very right, and the sample has been good, the result has been//wrong answer. I will not superstitious, it must be Bo Master blog has a mistake, I will Bo Master's//handed a pitch, however, Bo Master of the past, I have not. Ah, a sad, but the heart is again Ignite the fire of hope, or can make it. However, I have studied carefully, and I have made a few examples. The following group was found://4 2//a//c//t//gt//This set of examples, the answer should be 1, and my answer is 3. I suddenly suddenly realized that a single character is a virus, Cannot walk back to the root node. After understanding, a change, on AC, although the speed//a little slow, but I found myself on the understanding of AC automata has a little new expansion//Although as a rookie I dare to doubt is a good thing, but their wrong is wrong, do not// Because of their self-confidence to deliberately look for other people's mistakes, think others are wrong. Have a//dare to admit the wrong, and accept the right idea, and the understanding of the people, I feel the light, in the front! #include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #include < Queue>using namespace Std;typedef long long ll;const int max_node = 110;const ll MOD = 100000;const int max_n = 110;STR UCT matrix{ll mat[max_n][max_n];} Res;int n,m;struct Aho_corasick{int Ch[Max_node] [4];bool val[max_node];int f[max_node];//int last[max_node];int sz;void init () {memset (ch[0],-1,sizeof (ch[0])); val[0 ] = 0;sz = 1;f[0] = 0;//last[0] = 0;} int idx (char c) {if (c = = ' A ') return 0;if (c = = ' T ') return 1;if (c = = ' C ') return 2;return 3;} void Insert (char *s) {int u = 0;int n = strlen (s), for (int i=0;i<n;i++) {int c = idx (S[i]), if (ch[u][c]==-1) {memset (Ch[sz ],-1,sizeof (Ch[sz])); Val[sz] = 0;ch[u][c] = sz++;} U = ch[u][c];} Val[u] = true;} void Getfail () {queue<int> que;f[0] = 0;for (int c = 0;c < 4;c++) {int u = ch[0][c];if (u!=-1) {que.push (U); F[u] = 0 ;//last[u] = 0;} Else{ch[0][c] = 0;//indicates that when this C single character is not a virus, it can go back to root}}while (!que.empty ()) {int r = Que.front (); Que.pop (); if (Val[f[r]])// When a suffix of r is a virus mark this rval[r] = true;for (int c = 0; c < 4;c++) {int u = ch[r][c];if (U = =-1) {ch[r][c] = Ch[f[r]][c];//put non-existent Continue the edge of the bridge; Que.push (u); int v = f[r];while (v && ch[v][c]==-1) v = f[v];f[u] = Ch[v][c];//last[u] = Val[f[u]]? F[u]: Last[f[u] ";}}} void Get_matrix () {memset (res.mAt,0,sizeof (Res.mat)); for (int. u=0;u<sz;u++) {for (int c = 0;c < 4;c++) {if (!val[u] &&!val[ch[u][c]) res.ma t[u][ch[u][c]]++;}}}} Ac Matrix mulity (Matrix A,matrix b) {matrix ans;for (int i=0;i < ac.sz;i++) for (int j=0;j < ac.sz;j++) {Ans.mat[i][j] = 0 ; for (int k=0;k < AC.SZ; k++) ans.mat[i][j] = (Ans.mat[i][j] + a.mat[i][k] * B.mat[k][j])%mod;ans.mat[i][j]%= MOD;} return ans;} Matrix Matrix_power (Matrix A,int b) {matrix Ans;memset (ans.mat,0,sizeof (Ans.mat)); for (int i=0;i<ac.sz;i++) Ans.mat I [I] = 1;while (b) {if (b & 1) ans = mulity (ans,a); a = Mulity (a,a); b >>=1;} return ans;} void print (Matrix r) {for (int. i=0;i<ac.sz;i++) {for (int j=0;j<ac.sz;j++) cout << r.mat[i][j] << ""; cout << Endl;}} void input () {ac.init (); char s[20];for (int i=1;i<=m;i++) {scanf ("%s", s); Ac.insert (s);} Ac.getfail (); Ac.get_matrix ();//print (res); res = Matrix_power (res,n);//cout << Endl;//print (res); ll ans = 0;for ( int i=0;i<ac.sz;i++) {ans = (ans + res.mat[0][i])%mod;} cout << ans%mod << Endl;} int main () {//freopen ("1.txt", "R", stdin), while (scanf ("%d%d", &m,&n)!=eof) {//puts ("-------"); input ();} return 0;}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
POJ 2778 AC automaton + matrix fast power