HDU 2243 Postgraduate Entrance examination of the boundless--word complex (AC automata + matrix Power)
http://acm.hdu.edu.cn/showproblem.php?pid=2243
The following:
To give you multiple template strings, now ask you how many text strings that contain at least one template string in a text string that is no longer than l?
Analysis:
in fact, the subject is POJ 2778 deformation:
http://blog.csdn.net/u013480600/article/details/23467871
All we need to do is to have X in all strings that do not contain a template string of not more than L, and then use the total 26^1+26^2+ ... 26^l-x can be. Unsigned long long for the subject. Note: 26^1+26^2+ ... 26^l is a geometric progression, but because of the demand, so use formula definitely not. Here we still use the matrix power to calculate:
The sum=1+26+26^2+26^3...+26^n above, verify the results above to see if this is the case. Then we just need to ask for the N power of the 2*2 matrix. But note that the last sum needed is 1. Because sum consists of 1.
POJ 2778 We are asking for the number of text that does not contain a pattern string of length l, and now we ask for the number of strings of text that do not contain a pattern string longer than L . The f[i][n]==x represents the total number of methods that have gone n steps and have not traversed the word node at point I. We still find out (M is the number of robotic nodes):
F[i][n] =a0*f[0][n-1]+a1*f[1][n-1]+a2*f[2][n-1]+...+am-1*f[m-1][n-1]
Recursive matrix.
But here we're supposed to add a node to the AC automaton that represents the symbol ' yes ', which is the Terminator. Then any other valid characters including ' I ' can reach ' the ', but ' the successor ' is only himself. That is to say, no matter the first few steps, the current node can choose to go ' ", as long as it chooses to go '", then only continue to go ' ".
Assuming that the node number of ' is ' is SZ, then the transfer equation is:
F[sz][n] =f[0][n-1]+f[1][n-1]+....+f[sz][n-1]
The initial value f[i][0]=1 where I is a non word node (including the SZ node representing ' f[j][0]=0 '), where j is the word node.
The number of text with the final length <=l and does not contain any pattern strings is: f[0][l]+f[1][l]+f[2][l]+...f[sz][l]. Where F[sz][l] represents all of the true length of the <l, so only a legitimate string ending with ' a '.
That is, the previous matrix from the sz-1*sz-1 scale to the size of the Sz*sz, add the last row and the last column, where the last column except for the end of 1 others are 0, the last line is 1 (think carefully).
Note that one of our final results is illegal because the last mat^l takes the first column and the last node contains the empty string , so we want to-1 is the number of strings that do not contain the pattern string and the length does not exceed L.
AC Code: 31MS
#include <queue> #include <cstdio> #include <algorithm> #include <cstring> #include <cmath
> #include <iostream> using namespace std;
const int maxnode=35;
const int sigma_size=26;
struct Ac_automata {int ch[maxnode][sigma_size];
int Match[maxnode];
int F[maxnode];
int sz;
void Init () {sz=1;
memset (ch[0],0,sizeof (ch[0));
f[0]=match[0]=0;
} void Insert (char *s) {int N=strlen (s), u=0;
for (int i=0;i<n;i++) {int id=s[i]-' a ';
if (ch[u][id]==0) {ch[u][id]=sz;
memset (ch[sz],0,sizeof (Ch[sz));
match[sz++]=0;
} U=ch[u][id];
} match[u]=1;
} void Getfail () {f[0]=0;
Queue<int> Q;
for (int i=0;i<sigma_size;i++) {int u=ch[0][i];
if (u) {f[u]=0; Q.push (U);
} while (!q.empty ()) {int R=q.front (); Q.pop ();
for (int i=0;i<sigma_size;i++) {int u=ch[r][i];
if (!u) {ch[r][i]=ch[f[r]][i]; continue;}
Q.push (U);//missed this sentence before, looking for a bug for a long time. I rub int v=f[r];
while (v && ch[v][i]==0) v=f[v];
F[u]=ch[v][i];
Match[u] |= Match[f[u]];
}
}
}
};
Ac_automata AC;
unsigned long long z[maxnode][maxnode];
unsigned long long mat[maxnode][maxnode],mat2[maxnode][maxnode];
unsigned long long ans[maxnode][maxnode],ans2[maxnode][maxnode]; void mutiply (unsigned long long x[maxnode][maxnode], unsigned long long y[maxnode][maxnode],int sz) {for (int i=0;i<
; =sz;i++) {for (int j=0;j<=sz;j++) {z[i][j]=0;
for (int k=0;k<=sz;k++) {Z[i][j] + = x[i][k]*y[k][j];
} to (int i=0;i<=sz;i++) for (int j=0;j<=sz;j++) Y[I][J]=Z[I][J];
int main () {int n,l;
while (scanf ("%d%d", &n,&l) ==2) {ac.init ();
memset (Mat,0,sizeof (MAT));
memset (ANS) (ans,0,sizeof);
memset (mat2,0,sizeof (MAT2));
memset (ans2,0,sizeof (ANS2));
for (int i=0;i<n;i++) {char str[20];
scanf ("%s", str);
Ac.insert (str);
} ac.getfail ();
for (int i=0;i<ac.sz;i++) if (ac.match[i]==0) for (int j=0;j<sigma_size;j++)
if (ac.match[ac.ch[i][j]]==0) mat[ac.ch[i][j]][i]++;
for (int i=0;i<=ac.sz;i++) {mat[ac.sz][i]=1;
Ans[i][i]=1;
int m=l;
while (m) {if (m&1) mutiply (MAT,ANS,AC.SZ);
Mutiply (MAT,MAT,AC.SZ);
m>>=1; } UNSigned long long no_pattern_sum = 0;
for (int i=0;i<=ac.sz;i++) No_pattern_sum + = ans[i][0]; No_pattern_sum = no_pattern_sum-1//Subtract empty string unsigned long long res=0;//to calculate 26+26^2+26^3+.
The mat2[0][0]=1,mat2[0][1]=26 of 26^l;
mat2[1][0]=0,mat2[1][1]=26;
Ans2[0][0]=ans2[1][1]=1;
M=l;
while (m) {if (m&1) mutiply (mat2,ans2,1);
Mutiply (mat2,mat2,1);
m>>=1;
res = ans2[0][0]+ans2[0][1]-1;
printf ("%i64u\n", res-no_pattern_sum);
return 0;
}