zoukankan      html  css  js  c++  java
  • [poj2778]DNA Sequence(AC自动机+矩阵快速幂)

    题意:有m种DNA序列是有疾病的,问有多少种长度为n的DNA序列不包含任何一种有疾病的DNA序列。(仅含A,T,C,G四个字符)

    解题关键:AC自动机,实际上就是一个状态转移图,注意能少取模就少取模,尤其是在快速幂的时候,消耗时间极其巨大,此题效率差10倍。

    先+=在进行取模,两者分开,也可以快1倍。

    按照AC自动机建立邻接矩阵,其中不含病毒模式串的位置可以到达,

    其中上图矩阵为:

    2 1 0 0 1

    2 1 1 0 0

    1 1 0 1 1

    2 1 0 0 1

    2 1 0 0 1

    去掉病毒结点之后,变为

    2 1

    2 1

    转移方程:$dp[u] = sumlimits_{v -  > u} {dp[v]} $

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #include<cstdlib>
      5 #include<cstring>
      6 #include<iostream>
      7 #include<queue>
      8 using namespace std;
      9 typedef long long ll;
     10 const int N=4;
     11 const int MAXN=101;
     12 struct mat{
     13     ll m[101][101];
     14 };
     15 ll m,n;
     16 ll mod=100000;
     17 struct Trie{
     18     int Next[MAXN][N],Fail[MAXN],root,tot;
     19     bool End[MAXN];
     20     int newnode(){
     21         for(int i=0;i<N;i++) Next[tot][i]=-1;
     22         End[tot++]=false;
     23         return tot-1;
     24     }
     25     void init(){
     26         tot=0;
     27         root=newnode();
     28     }
     29     void insert(char buf[]){
     30         int len=strlen(buf),now=root,k;
     31         for(int i=0;i<len;i++){
     32             if(buf[i]=='A') k=0;
     33             else if(buf[i]=='G') k=1;
     34             else if(buf[i]=='C') k=2;
     35             else k=3;
     36             if(Next[now][k]==-1)  Next[now][k]=newnode();
     37             now=Next[now][k];
     38         }
     39         End[now]=true;
     40     }
     41     void build(){
     42         queue<int>que;
     43         Fail[root]=root;
     44         for(int i=0;i<N;i++){ 
     45             if(Next[root][i]==-1) Next[root][i]=root;
     46             else{
     47                 Fail[Next[root][i]]=root;
     48                 que.push(Next[root][i]);
     49             }
     50         } 
     51         while(!que.empty()){
     52             int now=que.front();
     53             que.pop();
     54             if(End[Fail[now]]) End[now]=true;
     55             for(int i=0;i<N;i++){
     56                 if(Next[now][i]==-1) Next[now][i]=Next[Fail[now]][i];
     57                 else{
     58                     Fail[Next[now][i]]=Next[Fail[now]][i];
     59                     que.push(Next[now][i]);
     60                 }
     61             }
     62         }
     63     }
     64     mat get_mat(int len){
     65         mat B={0};
     66         for(int i=0;i<len;i++){
     67             for(int j=0;j<N;j++){
     68                 if(End[Next[i][j]]==false) B.m[i][Next[i][j]]++;//不能直接置1 
     69             }
     70         }
     71         return B;
     72     }
     73 };
     74 
     75 mat mul(mat &A,mat &B,int len){
     76     mat C={0};
     77     for(int i=0;i<len;i++){
     78         for(int j=0;j<len;j++){
     79             for(int k=0;k<len;k++){
     80                 C.m[i][j]+=A.m[i][k]*B.m[k][j];
     81             }
     82             C.m[i][j]%=mod;
     83         }
     84     }
     85     return C;
     86 }
     87 
     88 mat pow(mat A,ll n,int len){
     89     mat B={0};
     90     for(int i=0;i<len;i++) B.m[i][i]=1;
     91     while(n){
     92         if(n&1) B=mul(B,A,len);
     93         A=mul(A,A,len);
     94         n>>=1;
     95     }
     96     return B;
     97 }
     98 
     99 Trie ac;
    100 char buf[10];
    101 int main(){
    102     while(scanf("%lld%lld",&m,&n)!=EOF){
    103         ac.init();
    104         for(int i=0;i<m;i++){
    105             scanf("%s",buf);
    106             ac.insert(buf);
    107         }
    108         ac.build();
    109         mat B=ac.get_mat(ac.tot);
    110         B=pow(B,n,ac.tot);
    111         ll res=0;
    112         for(int i=0;i<ac.tot;i++){
    113             res+=B.m[0][i];
    114         }
    115         printf("%lld
    ",res%mod);
    116     }
    117     return 0;
    118 }
  • 相关阅读:
    1021 个位数统计
    1020 月饼
    1019 数字黑洞
    1018 锤子剪刀布
    1017 A除以B
    1016 部分A+B
    1015 德才论
    1014 福尔摩斯的约会
    cocos2d 间隔动作
    cocos2d 瞬时动作
  • 原文地址:https://www.cnblogs.com/elpsycongroo/p/7511693.html
Copyright © 2011-2022 走看看