记录个DFA的模版POJ2778
DFA+矩阵乘法
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long llg;
const int N = 105;
const int P = 100000;
struct node
{
int flag, index;
node *pre, *next[4];
void init()
{
flag = index = 0;
pre = 0;
memset(next, 0, sizeof(next));
}
}trie[N];
node *root, *queue[N];
int m, tot, n;
llg matrix[N][N], c[N][N];
char str[15];
int getCode(char c)
{
switch(c)
{
case 'A': return 0;
case 'T': return 1;
case 'G': return 2;
case 'C': return 3;
default: cout<<"input error a??"<<endl;
}
}
void insertString(node *root, char *str)
{
int i, lab, len = strlen(str);
for(i = 0; i < len; i++)
{
lab = getCode(str[i]);
if(root->next[lab] == 0)
{
root->next[lab] = &trie[++tot];
root->next[lab]->init();
root->next[lab]->index = tot;
}
root = root->next[lab];
}
root->flag = 1;
}
void buildAC()
{
int i, head, tail;
node *u, *tmp;
root->pre = root;
head = tail = 0;
queue[0] = root;
while(head <= tail)
{
u = queue[head++];
for(i = 0; i < 4; i++)
if(u->next[i] == 0)
{
if(u == root) u->next[i] = root;
else u->next[i] = u->pre->next[i];
}
else
{
if(u == root) u->next[i]->pre = root;
else u->next[i]->pre = u->pre->next[i];
queue[++tail] = u->next[i];
}
tmp = u->pre;
if(u->flag == 0)
while(tmp != root)
{
if(tmp->flag)
{
u->flag = 1;
break;
}
tmp = tmp->pre;
}
}
}
void generateMatrix()
{
int i, j;
node *u;
memset(matrix, 0, sizeof(matrix));
for(i = 0; i <= tot; i++)
{
u = &trie[i];
if(u->flag == 0)
for(j = 0; j < 4; j++)
if(u->next[j]->flag == 0)
matrix[i][u->next[j]->index]++;
}
}
void multiply(llg a[][N], llg b[][N], llg target[][N])
{
int i, j, k;
llg tmp[N][N];
for(i = 0; i <= tot; i++)
for(j = 0; j <= tot; j++)
{
tmp[i][j] = 0;
for(k = 0; k <= tot; k++)
tmp[i][j] += a[i][k]*b[k][j];
tmp[i][j] %= P;
}
for(i = 0; i <= tot; i++)
for(j = 0; j <= tot; j++)
target[i][j] = tmp[i][j];
}
void calAns(int n)
{
int i, j;
llg ans = 0;
for(i = 0; i <= tot; i++)
for(j = 0; j <= tot; j++)
c[i][j] = matrix[i][j];
n--;
while(n)
{
if(n & 1) multiply(c, matrix, c);
multiply(matrix, matrix, matrix);
n >>= 1;
}
for(i = 0; i <= tot; i++) ans = (ans + c[0][i]) % P;
printf("%I64d\n", ans);
}
int main()
{
int i;
scanf("%d%d", &m, &n);
tot = 0;
root = &trie[0];
root->init();
for(i = 0; i < m; i++)
{
scanf(" %s", str);
insertString(root, str);
}
buildAC();
generateMatrix();
calAns(n);
return 0;
}