• 线性代数(矩阵乘法):POJ 2778 DNA Sequence


    DNA Sequence
     

    Description

    It's well known that DNA Sequence is a sequence only contains A, C, T and G, and it's very useful to analyze a segment of DNA Sequence,For example, if a animal's DNA sequence contains segment ATC then it may mean that the animal may have a genetic disease. Until now scientists have found several those segments, the problem is how many kinds of DNA sequences of a species don't contain those segments.

    Suppose that DNA sequences of a species is a sequence that consist of A, C, T and G,and the length of sequences is a given integer n.

    Input

    First line contains two integer m (0 <= m <= 10), n (1 <= n <=2000000000). Here, m is the number of genetic disease segment, and n is the length of sequences.

    Next m lines each line contain a DNA genetic disease segment, and length of these segments is not larger than 10.

    Output

    An integer, the number of DNA sequences, mod 100000.

    Sample Input

    4 3
    AT
    AC
    AG
    AA
    

    Sample Output

    36
      
    思路是这样的:把所有病毒片段放入AC自动机中,建立fail数组。如果一个状态的fail为病毒节点,则他自己也为病毒节点。最后按边建矩阵,快速幂。
      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdio>
      4 #include <queue>
      5 using namespace std;
      6 const int maxn=110;
      7 const int mod=100000;
      8 typedef unsigned long long ull;
      9 struct Matrix{
     10     int n;
     11     ull mat[maxn][maxn];
     12     Matrix(int n_,int on=0){
     13         n=n_;memset(mat,0,sizeof(mat));
     14         if(on)for(int i=1;i<=n;i++)mat[i][i]=1;
     15     }
     16     Matrix operator *(Matrix a){
     17         Matrix ret(n);
     18         unsigned long long l;
     19         for(int i=1;i<=n;i++)
     20             for(int k=1;k<=n;k++){
     21                 l=mat[i][k];
     22                 for(int j=1;j<=n;j++)
     23                     (ret.mat[i][j]+=l*a.mat[k][j]%mod)%=mod;    
     24             }
     25         return ret;    
     26     }
     27     Matrix operator ^(long long k){
     28         Matrix ret(n,1);
     29         while(k){
     30             if(k&1)
     31                 ret=ret**this;
     32             k>>=1;
     33             *this=*this**this;    
     34         }
     35         return ret;
     36     }
     37 };
     38 
     39 struct AC_automation{
     40     bool tag[maxn];
     41     int cnt,rt,ch[maxn][4],fail[maxn];
     42     AC_automation(){
     43         memset(tag,0,sizeof(tag));
     44         memset(fail,0,sizeof(fail));
     45         memset(ch,0,sizeof(ch));cnt=rt=1;
     46     }
     47     
     48     int ID(char c){
     49         if(c=='A')return 0;
     50         else if(c=='C')return 1;
     51         else if(c=='G')return 2;
     52         else return 3;
     53     }
     54     
     55     void Insert(char *s){
     56         int len=strlen(s),p=rt;
     57         for(int i=0;i<len;i++)
     58             if(ch[p][ID(s[i])])
     59                 p=ch[p][ID(s[i])];
     60             else
     61                 p=ch[p][ID(s[i])]=++cnt;
     62         tag[p]=true;
     63     }
     64     
     65     void Build(){
     66         queue<int>q;
     67         for(int i=0;i<4;i++)
     68             if(ch[rt][i])
     69                 fail[ch[rt][i]]=rt,q.push(ch[rt][i]);
     70             else
     71                 ch[rt][i]=rt;
     72         
     73         while(!q.empty()){
     74             int x=q.front();q.pop();
     75             for(int i=0;i<4;i++)
     76                 if(ch[x][i]){
     77                     fail[ch[x][i]]=ch[fail[x]][i];
     78                     tag[ch[x][i]]|=tag[fail[ch[x][i]]];
     79                     q.push(ch[x][i]);
     80                 }
     81                 else
     82                     ch[x][i]=ch[fail[x]][i];
     83         }
     84     }
     85     
     86     void Solve(int k){
     87         Matrix A(cnt);    
     88         for(int i=1;i<=cnt;i++)
     89             for(int j=0;j<4;j++)
     90                 if(!tag[i]&&!tag[ch[i][j]])
     91                     A.mat[ch[i][j]][i]+=1;
     92         A=A^k;
     93         long long ans=0;
     94         for(int i=1;i<=cnt;i++)
     95             ans+=A.mat[i][1];
     96         printf("%lld
    ",ans%mod);
     97     }
     98 }ac;
     99 char s[maxn];
    100 
    101 int main(){
    102 #ifndef ONLINE_JUDGE
    103     //freopen("","r",stdin);
    104     //freopen("","w",stdout);
    105 #endif
    106     int tot,n;
    107     scanf("%d%d",&tot,&n);
    108     while(tot--){
    109         scanf("%s",s);
    110         ac.Insert(s);
    111     }
    112     ac.Build();
    113     ac.Solve(n);
    114     return 0;    
    115 }
    尽最大的努力,做最好的自己!
  • 相关阅读:
    数据结构与算法习题总结——树结构
    SQL入门题集及学习笔记
    nlp入门系列笔记——阿里天池新闻文本新手赛
    linux一步一脚印--- ls -l 命令执行显示结果的每一列含义
    Python tuple元组---学习总结
    Python——列表深浅拷贝
    Python list列表---学习总结
    linux一步一脚印---mv命令
    linux一步一脚印---rm命令
    linux一步一脚印---cp命令
  • 原文地址:https://www.cnblogs.com/TenderRun/p/5569711.html
Copyright © 2020-2023  润新知