POJ 2778 DNA SequenceAC自动机 矩阵快速幂

    xiaoxiao2025-09-11  533

    #include <iostream> #include <string.h> #include <stdio.h> #include <algorithm> #include <queue> #include <math.h> #define mod 100000 #define LL long long using namespace std; const int M = 4; const int N = 1e6+10; struct Matrix{ int mat[110][110]; int n; Matrix(){} Matrix(int nn){ n = nn; 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 = (LL)mat[i][k]*b.mat[k][j]%mod; ret.mat[i][j]=(ret.mat[i][j]+tmp)%mod; } } } return ret; } }; struct Trie{ int next[N][M],fail[N]; bool end[N]; int root,L; int getIndex(char ch){ switch(ch){ case 'A': return 0; case 'C': return 1; case 'G': return 2; case 'T': return 3; } } int newNode(){ for(int i = 0; i < M; ++i){ next[L][i] = -1; } end[L++] = false; return L-1; } void init(){ L = 0; root = newNode(); } void insert(char buf[]){ int now = root; for(int i = 0 ; buf[i]; ++i){ int x = getIndex(buf[i]); if(next[now][x] == -1){ next[now][x] = newNode(); } now = next[now][x]; } end[now] = true; } void build(){ queue<int>Q; for(int i = 0; i < M; ++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 < M; ++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]); } } } } //计算的是选择0个、1个、、、n个的总数目 // Matrix getMatrix(){ // Matrix res = Matrix(1+L); // for(int i = 0; i < L; ++i){ // for(int j = 0; j < M; ++j) // if(end[next[i][j]] == false) // res.mat[i][next[i][j]]++; // } // for(int i = 0; i < L+1; ++i){ // res.mat[i][L] = 1; // } // return res; // } //计算选择n个的数目 Matrix getMatrix(){ Matrix res = Matrix(L); for(int i = 0; i < L; ++i){ for(int j = 0; j < M; ++j) if(end[next[i][j]] == false) res.mat[i][next[i][j]]++; } return res; } }; Trie ac; char buf[20]; Matrix pow_Matrix(Matrix a,int n){ Matrix ret = Matrix(a.n); for(int i = 0; i < ret.n; ++i) ret.mat[i][i] = 1; while(n){ if(n&1){ ret = ret*a; } a = a*a; n >>= 1; } return ret; } int main() { int n,m; while(~scanf("%d%d",&n,&m)){ ac.init(); for(int i = 0; i < n; ++i){ scanf("%s",buf); ac.insert(buf); } ac.build(); Matrix a = ac.getMatrix(); a = pow_Matrix(a,m); int ans = 0; for(int i = 0; i < a.n; ++i){ ans =(ans+a.mat[0][i])%mod; } printf("%d\n",ans); } return 0; }
    转载请注明原文地址: https://ju.6miu.com/read-1302529.html
    最新回复(0)