标签:
题目链接:DNA Sequence
解析:AC自动机 + 矩阵加速(快速幂)。
这个时候AC自动机 的一种状态转移图的思路就很透彻了,AC自动机就是可以确定状态的转移。
AC代码:
#include <iostream> #include <cstdio> #include <queue> #include <cstring> using namespace std; const int MOD = 100000; struct Matrix{ int mat[110][110], n; Matrix(){} Matrix(int _n){ n = _n; for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) mat[i][j] = 0; } Matrix operator *(const Matrix &b) const{ Matrix ret = Matrix(n); for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) for(int k = 0; k < n; k++){ int tmp = (long long)mat[i][k] * b.mat[k][j] % MOD; ret.mat[i][j] = (ret.mat[i][j] + tmp) % MOD; } return ret; } }; struct Trie{ int next[110][4], fail[110]; bool end[110]; int root, L; int newnode(){ for(int i = 0; i < 4; i++) next[L][i] = -1; end[L++] = false; return L-1; } void init(){ L = 0; root = newnode(); } int getch(char ch){ if(ch == 'A') return 0; if(ch == 'C') return 1; if(ch == 'G') return 2; else return 3; } void insert(char s[]){ int len = strlen(s); int now = root; for(int i = 0; i < len; i++){ if(next[now][getch(s[i])] == -1) next[now][getch(s[i])] = newnode(); now = next[now][getch(s[i])]; } end[now] = true; } void build(){ queue<int> Q; for(int i = 0; i < 4; i ++){ if(next[root][i] == -1) next[root][i] = root; else{ fail[ next[root][i] ] = root; Q.push(next[root][i]); } } while(!Q.empty()){ int now = Q.front(); Q.pop(); if(end[ fail[now] ] == true) end[now] = true; for(int i = 0; i < 4; i ++){ if(next[now][i] == -1) next[now][i] = next[ fail[now] ][i]; else{ fail[ next[now][i] ] = next[ fail[now] ][i]; Q.push(next[now][i]); } } } } Matrix getMatrix(){ Matrix ret = Matrix(L); for(int i = 0; i < L; i ++) for(int j = 0; j < 4; j ++) if(end[ next[i][j] ] == false) ret.mat[i][ next[i][j] ] ++; return ret; } }; Trie ac; char buf[20]; Matrix pow_Mat(Matrix a, int n){ //快速幂 Matrix ret = Matrix(a.n); for(int i = 0; i < ret.n; i ++) ret.mat[i][i] = 1; Matrix tmp = a; while(n){ if(n & 1) ret = ret * tmp; tmp = tmp * tmp; n >>= 1; } return ret; } int main(){ #ifdef sxk freopen("in.txt", "r", stdin); #endif //sxk int n, m; while(scanf("%d%d", &m, &n) == 2){ ac.init(); for(int i = 0; i < m; i ++){ scanf("%s", buf); ac.insert(buf); } ac.build(); Matrix a = ac.getMatrix(); a = pow_Mat(a, n); int ans = 0; for(int i = 0; i < a.n; i ++) ans = (ans + a.mat[0][i]) % MOD; printf("%d\n", ans); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
POJ 2778 DNA Sequence (AC自动机 + 矩阵快速幂)
标签:
原文地址:http://blog.csdn.net/u013446688/article/details/47378255