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

来源:互联网 发布:vim如何c语言高亮 编辑:程序博客网 时间:2024/06/07 03:50
#include <iostream>#include <string.h>#include <stdio.h>#include <algorithm>#include <queue>#include <math.h>#define mod 100000#define LL long longusing 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;}

0 0
原创粉丝点击