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 }