POJ 2778 DNA Sequence(AC自动机+DP)

题目链接

这题在经过强哥讲解,看了很多题解之后AC了,矩阵乘法回顾了一下,然后AC自动机换了一份模版。。。慢慢理解。。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<string>
  5 using namespace std;
  6 #define N 1000001
  7 #define LL __int64
  8 int t;
  9 int tire[N][4];
 10 int que[N];
 11 int o[N];
 12 int fail[N];
 13 LL p[101][101],mat[101][101];
 14 void CL()
 15 {
 16     memset(tire,-1,sizeof(tire));
 17     t = 1;
 18 }
 19 int judge(char s)
 20 {
 21     switch(s)
 22     {
 23     case'A':
 24         return 0;
 25     case'C':
 26         return 1;
 27     case'G':
 28         return 2;
 29     case'T':
 30         return 3;
 31     }
 32     return 0;
 33 }
 34 void insert(char *s)
 35 {
 36     int i,root,len;
 37     len = strlen(s);
 38     root = 0;
 39     for(i = 0; i < len; i ++)
 40     {
 41         if(tire[root][judge(s[i])] == -1)
 42             tire[root][judge(s[i])] = t ++;
 43         root = tire[root][judge(s[i])];
 44     }
 45     o[root] = 1;
 46 }
 47 void build_ac()
 48 {
 49     int head,tail,front,i;
 50     head = tail = 0;
 51     for (i = 0; i < 4; i++)
 52     {
 53         if (tire[0][i]  != -1)
 54         {
 55             fail[tire[0][i]] = 0;
 56             que[tail++] = tire[0][i];
 57         }
 58         else
 59         {
 60             tire[0][i] = 0;
 61         }
 62     }
 63     while(head != tail)
 64     {
 65         front = que[head++];
 66         if(o[fail[front]])
 67             o[front] = 1;
 68         for(i = 0; i < 4; i ++)
 69         {
 70             if(tire[front][i] != -1)
 71             {
 72                 que[tail++] = tire[front][i];
 73                 fail[tire[front][i]] = tire[fail[front]][i];
 74             }
 75             else
 76             {
 77                 tire[front][i] = tire[fail[front]][i];
 78             }
 79         }
 80     }
 81 }
 82 void work()
 83 {
 84     int i,j;
 85     for(i = 0; i < t; i ++)
 86     {
 87         if(o[i]) continue;
 88         for(j = 0; j < 4; j ++)
 89         {
 90             if(o[tire[i][j]]) continue;
 91             p[i][tire[i][j]] ++;
 92         }
 93     }
 94 }
 95 int qmod(LL n,int MOD)
 96 {
 97     int i,j,k,ans = 0;
 98     LL c[101][101];
 99     while(n)
100     {
101         if(n&1)
102         {
103             memset(c,0,sizeof(c));
104             for(i = 0; i < t; i ++)
105                 for(j = 0; j < t; j ++)
106                     for(k = 0; k < t; k ++)
107                     {
108                         c[i][j] = c[i][j]+(mat[i][k]*p[k][j]);
109                         if(c[i][j] >= MOD)
110                         c[i][j] %= MOD;
111                     }
112             memcpy(mat,c,sizeof(mat));
113         }
114         memset(c,0,sizeof(c));
115         for(i = 0; i < t; i ++)
116             for(j = 0; j < t; j ++)
117                 for(k = 0; k < t; k ++)
118                 {
119                     c[i][j] = c[i][j]+(p[i][k]*p[k][j]);
120                     if(c[i][j] >= MOD)
121                     c[i][j] %= MOD;
122                 }
123         memcpy(p,c,sizeof(p));
124         n >>= 1;
125     }
126     for(i = 0; i < t; i ++)
127     {
128         if(o[i]) continue ;
129         ans += mat[0][i];
130         ans %= MOD;
131     }
132     return ans;
133 }
134 int main()
135 {
136     int i,j,m;
137     LL n;
138     char ch[21];
139     scanf("%d%I64d",&m,&n);
140     CL();
141     for(i = 1; i <= m; i ++)
142     {
143         scanf("%s",ch);
144         insert(ch);
145     }
146     build_ac();
147     work();
148     for(i = 0; i < t; i ++)
149     {
150         for(j = 0; j < t; j ++)
151         {
152             mat[i][j] = (i == j);
153         }
154     }
155     printf("%d\n",qmod(n,100000));
156     return 0;
157 }

 

 

posted @ 2013-04-24 10:22  Naix_x  阅读(158)  评论(0编辑  收藏  举报