DNA Sequence
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 11450 | Accepted: 4357 |
Description
It's well known that DNA Sequence is a sequence only contains A, C, T and G, and it's very useful to analyze a segment of DNA Sequence,For example, if a animal's DNA sequence contains segment ATC then it may mean that the animal may have a genetic disease. Until now scientists have found several those segments, the problem is how many kinds of DNA sequences of a species don't contain those segments.
Suppose that DNA sequences of a species is a sequence that consist of A, C, T and G,and the length of sequences is a given integer n.
Suppose that DNA sequences of a species is a sequence that consist of A, C, T and G,and the length of sequences is a given integer n.
Input
First line contains two integer m (0 <= m <= 10), n (1 <= n <=2000000000). Here, m is the number of genetic disease segment, and n is the length of sequences.
Next m lines each line contain a DNA genetic disease segment, and length of these segments is not larger than 10.
Next m lines each line contain a DNA genetic disease segment, and length of these segments is not larger than 10.
Output
An integer, the number of DNA sequences, mod 100000.
Sample Input
4 3 AT AC AG AA
Sample Output
36
Source
题意:
给n个DNA片段,然后问长度为m的DNA不包含所给DNA片段的DNA有多少种
01邻接矩阵A的K次方C=A^K,C[i][j]表示i点到j点正好经过K条边的路径数
#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <string>
#include <map>
#include <cmath>
#include <queue>
#include <set>
using namespace std;
//#define WIN
#ifdef WIN
typedef __int64 LL;
#define iform "%I64d"
#define oform "%I64d\n"
#define oform1 "%I64d"
#else
typedef long long LL;
#define iform "%lld"
#define oform "%lld\n"
#define oform1 "%lld"
#endif
#define S64I(a) scanf(iform, &(a))
#define P64I(a) printf(oform, (a))
#define P64I1(a) printf(oform1, (a))
#define REP(i, n) for(int (i)=0; (i)<n; (i)++)
#define REP1(i, n) for(int (i)=1; (i)<=(n); (i)++)
#define FOR(i, s, t) for(int (i)=(s); (i)<=(t); (i)++)
const int INF = 0x3f3f3f3f;
const double eps = 10e-9;
const double PI = (4.0*atan(1.0));
const int MAX_NODE = 200 + 20;
const int SIGMA_SIZE = 4;
const int mod = 100000;
struct Matrix {
int n, m;
LL mat[110][110];
Matrix(int n=0, int m=0) : n(n), m(m) {
memset(mat, 0, sizeof(mat));
}
};
struct ACAutomata {
int ch[MAX_NODE][SIGMA_SIZE];
bool val[MAX_NODE];
int f[MAX_NODE];
int sz;
void init() {
sz = 1; memset(ch[0], -1, sizeof(ch[0]));
val[0] = false;
}
int idx(char c) {
if(c == 'A') return 0;
if(c == 'C') return 1;
if(c == 'T') return 2;
if(c == 'G') return 3;
}
void insert(char * s) {
int n = strlen(s);
int u = 0;
for (int i=0; i<n; i++) {
int c = idx(s[i]);
if(-1 == ch[u][c]) {
memset(ch[sz], -1, sizeof(ch[sz]));
val[sz] = false;
ch[u][c] = sz++;
}
u = ch[u][c];
}
val[u] = true;
}
void build() {
queue<int> Q;
f[0] = 0;
for (int i=0; i<SIGMA_SIZE; i++) {
int u = ch[0][i];
if(u != -1) { Q.push(u); f[u] = 0; }
else ch[0][i] = 0;
}
while (!Q.empty()) {
int u = Q.front(); Q.pop();
if(val[f[u]]) val[u] = true;
for (int c=0; c<SIGMA_SIZE; c++) {
int v = ch[u][c];
if(-1 != v) {
Q.push(v);
f[v] = ch[f[u]][c];
} else {
ch[u][c] = ch[f[u]][c];
}
}
}
}
Matrix getMatrix() {
Matrix res(sz, sz);
for(int i=0; i<sz; i++) {
for(int j=0; j<4; j++) {
int son = ch[i][j];
if(son >= 0 && !val[i] && !val[son]) {
res.mat[i][son]++;
}
}
}
return res;
}
};
Matrix MatrixMult(Matrix m1, Matrix m2) {
Matrix res(m1.n, m2.m);
for(int i=0; i<res.n; i++) {
for(int j=0; j<res.m; j++) {
LL t = 0;
for(int k=0; k<m1.m; k++) {
t += m1.mat[i][k] * m2.mat[k][j];
t %= mod;
}
res.mat[i][j] = t;
}
}
return res;
}
Matrix MatrixPowMod(Matrix A, int n) {
Matrix di(A.n, A.n);
REP(i, di.n) REP(j, di.n)
di.mat[i][j] = i == j;
while(n) {
if(n&1) {
di = MatrixMult(di, A);
}
A = MatrixMult(A, A);
n >>= 1;
}
return di;
}
ACAutomata ac;
char dic[1020][60];
char s[2000000 + 20];
int main() {
int n, m;
while(scanf("%d%d", &n, &m) != EOF) {
ac.init();
for(int i=0; i<n; i++) {
scanf("%s", dic[i]);
ac.insert(dic[i]);
}
ac.build();
Matrix res = ac.getMatrix();
res = MatrixPowMod(res, m);
LL ans = 0;
for(int i=0; i<res.m; i++) {
ans += res.mat[0][i];
ans %= mod;
}
P64I(ans);
}
return 0;
}