• poj 2778 DNA Sequence AC自动机+矩阵快速幂


    题意:给定M个疾病DNA序列,求组成长度为N的DNA序列的个数,其字串不含疾病DNA,答案模100000。

     

    思路:AC自动机+矩阵快速幂

    先建自动机,注意某给定的疾病DNA序列是另一疾病DNA序列的子串的情况。 这种情况可以在建立失败链接的时候搞定。

    之后自动机上 每一个节点作为一个状态,总共node_num个状态node_num<=101。

    题目可以转换在一个有向图里,从i开始走k步一共有多少条路径。答案是有向图的邻接矩阵的k次方 输出G[i][1]+……+G[i][n]

    建立一个node_num*node_num 的矩阵 进行矩阵快速幂 具体转化详见http://hi.baidu.com/%D2%D5%C1%D6010/blog/item/6db06ccf0a3b440993457e7b.htm

      1 #include<iostream>
    2 #include<map>
    3 #include<cstring>
    4 using namespace std;
    5 #define MAXM 110
    6 #define mod 100000
    7 struct node
    8 {
    9 int name;
    10 int id;
    11 node *next[5];
    12 node *failink;
    13 node *father;
    14 bool end;
    15 node()
    16 {
    17 end=0;
    18 memset(next,0,sizeof(next));
    19 }
    20 };
    21 struct matrix
    22 {
    23 long long a[MAXM][MAXM];
    24 matrix()
    25 {
    26 memset(a,0,sizeof(a));
    27 }
    28 };
    29 node *head;
    30 node memo[MAXM];
    31 node *f[MAXM];
    32 int node_num=0;
    33 int top=0;
    34 node *Q[MAXM];
    35 matrix G;
    36 int m,n;
    37 matrix operator *(const matrix &x,const matrix &y)
    38 {
    39 int i,j,k;
    40 matrix ans;
    41 for(i=1;i<=node_num;i++)
    42 for(j=1;j<=node_num;j++)
    43 for(k=1;k<=node_num;k++)
    44 {
    45 ans.a[i][j]+=x.a[i][k]*y.a[k][j];
    46 if(ans.a[i][j]>=mod) ans.a[i][j]%=mod;
    47 }
    48 return ans;
    49 }
    50 int get(char c)
    51 {
    52 switch(c)
    53 {
    54 case 'A':return 1;
    55 case 'G':return 2;
    56 case 'C':return 3;
    57 case 'T':return 4;
    58 }
    59 }
    60 void insert(node *t,char c[],int i)
    61 {
    62 if(i==strlen(c))
    63 {
    64 t->end=1;
    65 return ;
    66 }
    67 int x=get(c[i]);
    68 if(t->next[x]==NULL)
    69 {
    70 node *p=&memo[top++];
    71 p->name=x; p->father=t; p->id=++node_num; f[node_num]=p;
    72 t->next[x]=p;
    73 }
    74 insert(t->next[x],c,i+1);
    75 }
    76 void set_fail_link()
    77 {
    78 int i,j;
    79 node *p,*t;
    80 int front,tail;
    81 Q[front=tail=1]=head;
    82 while(front<=tail)
    83 {
    84 p=Q[front++];
    85 if(p->father==head) p->failink=head;
    86 else if(p!=head)
    87 {
    88 t=p->father->failink;
    89 while(1)
    90 {
    91 if(t->next[p->name]!=NULL)
    92 {
    93 if(t->next[p->name]->end) p->end=1; //子串中有疾病DNA序列的情况
    94 p->failink=t->next[p->name];
    95 break;
    96 }
    97 else if(t==head)
    98 {
    99 p->failink=t;
    100 break;
    101 }
    102 else t=t->failink;
    103 }
    104 }
    105 for(i=1;i<=4;i++)
    106 if(p->next[i]!=NULL) Q[++tail]=p->next[i];
    107 }
    108 }
    109 void build_matrix()
    110 {
    111 int i,j;
    112 for(i=1;i<=node_num;i++)
    113 if(!f[i]->end)
    114 for(j=1;j<=4;j++)
    115 {
    116 if(f[i]->next[j]!=NULL&&f[i]->next[j]->end==0)
    117 G.a[i][f[i]->next[j]->id]++;
    118 else if(f[i]->next[j]==NULL)
    119 {
    120 if(i==0) G.a[0][0]++;
    121 else
    122 {
    123 node *p=f[i];
    124 while(p->next[j]==NULL)
    125 {
    126 if(p->id==1) break;
    127 p=p->failink;
    128 }
    129 if(p->next[j]!=NULL&&p->next[j]->end==0)
    130 G.a[i][p->next[j]->id]++;
    131 else if(p->id==1&&p->next[j]==NULL)
    132 G.a[i][1]++;
    133 }
    134 }
    135 }
    136 }
    137 int matrix_pow(int n)
    138 {
    139 matrix ans;
    140 int i,j;
    141 for(i=1;i<=node_num;i++) ans.a[i][i]=1;
    142 while(n>0)
    143 {
    144 if(n&1) ans=ans*G;
    145 G=G*G;
    146 n>>=1;
    147 }
    148 long long sum=0;
    149 for(i=1;i<=node_num;i++)
    150 sum+=ans.a[1][i];
    151 return sum%mod;
    152 }
    153
    154 int main()
    155 {
    156 char c[11];
    157 scanf("%d%d",&m,&n);
    158 head=&memo[top++]; head->father=NULL;
    159 head->id=++node_num; f[1]=head;
    160 int i,j;
    161 for(i=1;i<=m;i++)
    162 {
    163 scanf("%s",c);
    164 insert(head,c,0);
    165 }
    166 set_fail_link();
    167 build_matrix();
    168 printf("%d\n",matrix_pow(n));
    169 system("pause");
    170 return 0;
    171 }


    l
                                                                                               

  • 相关阅读:
    vimrc之fileformat
    std::copy ( myvector.begin(), myvector.end(), out_it )
    backtrace、backtrace_symbols
    mysql之replicate_do_table/replicate_ingore_table/replicate_wide_do_table/replicate_wide_ingore_table
    symbol lookup error
    mysql之select into outfile
    flex与bison
    运行maven打出来的jar包报错:Unable to locate Spring NamespaceHandler for XML schema namespace
    让maven生成可运行jar包
    windows下通过Git Bash使用Git常用命令
  • 原文地址:https://www.cnblogs.com/myoi/p/2344480.html
Copyright © 2020-2023  润新知