POJ2778-DNA Sequence
2017-11-12 15:53
381 查看
DNA Sequence
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
Sample Output
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;
}
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 18029 | Accepted: 6937 |
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;
}
相关文章推荐
- POJ 2778 DNA Sequence [AC自动机 矩阵乘法]
- POJ 2778 DNA Sequence && AC自动机 矩阵 矩阵加速
- POJ 2778 DNA Sequence [AC自动机 + 矩阵快速幂]
- POJ 题目2778 DNA Sequence(AC自动机,矩阵快速幂)
- poj2778.DNA Sequence (Trie图 && 矩阵乘)
- POJ2778 DNA Sequence (AC自动机+矩阵快速幂)
- POJ 2778 DNA Sequence(AC自动机+矩阵)
- POJ 2778 DNA Sequence(AC自动机 + 矩阵乘法)
- POJ 2778 DNA Sequence [AC自动机 + 矩阵快速幂]
- poj 2778:DNA Sequence
- poj 2778 DNA Sequence
- Poj 2778 DNA Sequence
- POJ 2778(DNA Sequence-Fail指针+矩阵快速幂)
- POJ 2778 DNA Sequence(AC自动机+矩阵快速幂)
- poj 2778 AC自动机+快速幂(DNA Sequence)
- poj2778--DNA Sequence(AC自动机+矩阵优化)
- poj 2778 DNA Sequence(AC自动机+矩阵快速幂)
- POJ 2778 DNA Sequence(AC自动机+矩阵快速幂+dp)
- poj2778 DNA Sequence(AC自动机+矩阵快速幂)
- POJ 2778 DNA Sequence (AC自动机 + 矩阵快速幂)