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 }

 

 

你可能感兴趣的:(sequence)