您的位置:首页 > 产品设计 > UI/UE

POJ2778-DNA Sequence

2017-11-12 15:53 381 查看
DNA Sequence

Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 18029 Accepted: 6937
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. 

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. 

Output

An integer, the number of DNA sequences, mod 100000.
Sample Input
4 3
AT
AC
AG
AA

Sample Output
36

Source

POJ Monthly--2006.03.26,dodo

题意:给出患病的DNA序列,问序列长度为n的,且不包含患病的DNA序列有多少种

解题思路:ac自动机+矩阵快速幂

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <cctype>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <vector>
#include <bitset>
#include <functional>

using namespace std;

#define LL long long
const int INF = 0x3f3f3f3f;

char ch[15];
int n, m;

char get(char ch)
{
if (ch == 'A') return 0;
if (ch == 'C') return 1;
if (ch == 'G') return 2;
else return 3;
}

struct Matrix
{
int v[110][110];
Matrix()
{
memset(v, 0, sizeof v);
}
} dan;

Matrix mul(Matrix a, Matrix b, int d)
{
Matrix ans;
for (int i = 0; i < d; i++)
for (int j = 0; j < d; j++)
for (int k = 0; k < d; k++)
(ans.v[i][j] += (1LL * a.v[i][k] * b.v[k][j]) % 100000) %= 100000;
return ans;
}

Matrix pow(Matrix a, int k, int d)
{
Matrix ans = dan;
while (k)
{
if (k & 1) ans = mul(ans, a, d);
k >>= 1;
a = mul(a, a, d);
}
return ans;
}

struct Trie
{
int next[110][4], fail[110], flag[110];
int root, tot;
int newnode()
{
for (int i = 0; i < 4; i++) next[tot][i] = -1;
flag[tot++] = 0;
return tot - 1;
}
void init()
{
tot = 0;
root = newnode();
}
void insert(char ch[])
{
int k = root;
for (int i = 0; ch[i]; i++)
{
if (next[k][get(ch[i])] == -1) next[k][get(ch[i])] = newnode();
k = next[k][get(ch[i])];
}
flag[k] = 1;
}
void build()
{
queue<int>q;
fail[root] = root;
for (int i = 0; i < 4; i++)
{
if (next[root][i] == -1) next[root][i] = root;
else
{
fail[next[root][i]] = root;
q.push(next[root][i]);
}
}
while (!q.empty())
{
int pre = q.front();
q.pop();
if (flag[fail[pre]]) flag[pre] = 1;
for (int i = 0; i < 4; i++)
{
if (next[pre][i] == -1) next[pre][i] = next[fail[pre]][i];
else
{
fail[next[pre][i]] = next[fail[pre]][i];
q.push(next[pre][i]);
}
}
}
}
void solve()
{
Matrix ans;
for (int i = 0; i < tot; i++)
for (int j = 0; j < 4; j++)
if (!flag[next[i][j]]) ans.v[i][next[i][j]]++;
for (int i = 0; i < tot; i++) dan.v[i][i] = 1;
ans = pow(ans, m, tot);
int sum = 0;
for (int i = 0; i < tot; i++) (sum += ans.v[0][i]) %= 100000;
printf("%d\n", sum);
}
void debug()
{
for (int i = 0; i < tot; i++)
{
printf("id = %3d,fail = %3d,end = %3d,chi = [", i, fail[i], flag[i]);
for (int j = 0; j < 26; j++) printf("%2d", next[i][j]);
printf("]\n");
}
}
}ac;

int main()
{
while (~scanf("%d %d", &n, &m))
{
ac.init();
for (int i = 1; i <= n; i++)
{
scanf("%s", ch);
ac.insert(ch);
}
ac.build();
ac.solve();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: