DNA Sequence
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 19991   Accepted: 7603

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

题意:

给定m个致病基因序列。问长度为n的DNA序列中有多少个是没有这些序列的。

思路:

这道题用到AC自动机的状态转移的性质了。

当我建好了状态图之后,在某一个状态a时,我可以知道他可以到达的所有状态。Trie树上的一个节点就是一个状态。

初始矩阵mat[i][j]表示的是从状态i走一步到状态j有几种可能。使用矩阵快速幂,对这个矩阵做n次幂,就可以得到每个两个状态之间走n次总共有多少方案。

对于一个长为n的串,没有任何一个致病基因序列,那么所有致病基因转移过去的状态都不能算进去。

我们给每一个致病基因做一个危险标记,同时要注意所有fail可以到达的节点如果是danger的,他自己也要变成danger

因为这段致病基因作为后缀出现在这个串中了。

 #include <iostream>
#include <set>
#include <cmath>
#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
//#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
#define inf 0x7f7f7f7f int m, n;
const int maxn = ;
const int maxlen = 2e6 + ; struct Matrix
{
unsigned long long mat[][];
int n;
Matrix(){}
Matrix(int _n)
{
n=_n;
for(int i=;i<n;i++)
for(int j=;j<n;j++)
mat[i][j] = ;
}
Matrix operator *(const Matrix &b)const
{
Matrix ret = Matrix(n);
for(int i=;i<n;i++)
for(int j=;j<n;j++)
for(int k=;k<n;k++)
ret.mat[i][j]+=mat[i][k]*b.mat[k][j] % ;
return ret;
}
void print()
{
for(int i = ; i < n; i++){
for(int j = ; j < n; j++){
printf("%d ", mat[i][j]);
}
printf("\n");
}
}
}; unsigned long long pow_m(unsigned long long a, int n)
{
unsigned long long ret = ;
unsigned long long tmp = a;
while(n){
if(n & )ret *= tmp;
tmp *= tmp;
n >>= ;
}
return ret;
} Matrix pow_M(Matrix a, int n)
{
Matrix ret = Matrix(a.n);
for(int i = ; i < a.n; i++){
ret.mat[i][i] = ;
}
Matrix tmp = a;
//cout<<a.n<<endl;
while(n){
if(n & )ret = ret * tmp;
tmp = tmp * tmp;
n >>= ;
//ret.print();
//cout<<endl;
}
return ret;
} struct tree{
int fail;
int son[];
bool danger;
}AC[maxlen];
int tot = , id[];
char s[]; void build(char s[])
{
int len = strlen(s);
int now = ;
for(int i = ; i < len; i++){
int x = id[s[i]];
if(AC[now].son[x] == ){
AC[now].son[x] = ++tot;
}
now = AC[now].son[x];
}
AC[now].danger = true;
} void get_fail()
{
queue<int>que;
for(int i = ; i < ; i++){
if(AC[].son[i] != ){
AC[AC[].son[i]].fail = ;
que.push(AC[].son[i]);
}
}
while(!que.empty()){
int u = que.front();
que.pop();
for(int i = ; i < ; i++){
if(AC[u].son[i] != ){
AC[AC[u].son[i]].fail = AC[AC[u].fail].son[i];
que.push(AC[u].son[i]);
}
else{
AC[u].son[i] = AC[AC[u].fail].son[i];
}
int x = AC[AC[u].son[i]].fail;
if(AC[x].danger){
AC[AC[u].son[i]].danger = true;
}
}
}
} /*int AC_query(char s[])
{
int len = strlen(s);
int now = 0, cnt = 0;
for(int i = 0; i < len; i++){
int x = id[s[i]];
now = AC[now].son[x];
for(int t = now; t; t = AC[t].fail){
if(!AC[t].vis && AC[t].ed != 0){
cnt++;
AC[t].vis = true;
}
}
}
return cnt;
}*/ Matrix getMatrix()
{
Matrix ret = Matrix(tot + );
//int now = 0;
for(int i = ; i < tot + ; i++){
if(AC[i].danger)continue;
for(int j = ; j < ; j++){
if(AC[AC[i].son[j]].danger == false){
ret.mat[i][AC[i].son[j]]++;
}
}
}
for(int i = ; i < tot + ; i++){
ret.mat[i][tot] = ;
}
return ret;
} int main()
{
id['A'] = ;id['T'] = ;id['C'] = ;id['G'] = ;
//cout<<1<<endl;
while(~scanf("%d%d", &m, &n)){
for(int i = ; i <= tot; i++){
AC[i].fail = ;
AC[i].danger = false;
for(int j = ; j < ; j++){
AC[i].son[j] = ;
}
}
tot = ;
for(int i = ; i <= m; i++){
scanf("%s", s);
build(s);
}
AC[].fail = ;
get_fail();
Matrix mmm = Matrix(tot + );
//int now = 0;
for(int i = ; i < tot + ; i++){
if(AC[i].danger)continue;
for(int j = ; j < ; j++){
if(AC[AC[i].son[j]].danger == false){
mmm.mat[i][AC[i].son[j]]++;
}
}
} mmm = pow_M(mmm, n);
unsigned long long res = ;
for(int i = ; i < mmm.n; i++){
res = (res + mmm.mat[][i]) % ;
} printf("%lld\n", res);
}
//getchar();
return ;
}

poj2778 DNA Sequence【AC自动机】【矩阵快速幂】的更多相关文章

  1. [poj2778]DNA Sequence(AC自动机+矩阵快速幂)

    题意:有m种DNA序列是有疾病的,问有多少种长度为n的DNA序列不包含任何一种有疾病的DNA序列.(仅含A,T,C,G四个字符) 解题关键:AC自动机,实际上就是一个状态转移图,注意能少取模就少取模, ...

  2. poj2778 DNA Sequence(AC自动机+矩阵快速幂)

    Description It's well known that DNA Sequence is a sequence only contains A, C, T and G, and it's ve ...

  3. poj 2778 DNA Sequence ac自动机+矩阵快速幂

    链接:http://poj.org/problem?id=2778 题意:给定不超过10串,每串长度不超过10的灾难基因:问在之后给定的长度不超过2e9的基因长度中不包含灾难基因的基因有多少中? DN ...

  4. poj2778DNA Sequence (AC自动机+矩阵快速幂)

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud DNA Sequence Time Limit: 1000MS   Memory ...

  5. POJ2778 DNA Sequence(AC自动机 矩阵)

    先使用AC自动机求得状态转移关系,再建立矩阵,mat[i][j]表示一步可从i到j且i,j节点均非终止字符的方案数,则此矩阵的n次方表示n步从i,到j的方法数. #include<cstdio& ...

  6. POJ2778 DNA Sequence(AC自动机+矩阵快速幂)

    题目给m个病毒串,问不包含病毒串的长度n的DNA片段有几个. 感觉这题好神,看了好久的题解. 所有病毒串构造一个AC自动机,这个AC自动机可以看作一张有向图,图上的每个顶点就是Trie树上的结点,每个 ...

  7. POJ 2778 DNA Sequence (ac自动机+矩阵快速幂)

    DNA Sequence Description It's well known that DNA Sequence is a sequence only contains A, C, T and G ...

  8. DNA Sequence POJ - 2778 AC自动机 && 矩阵快速幂

    It's well known that DNA Sequence is a sequence only contains A, C, T and G, and it's very useful to ...

  9. POJ 2778 DNA Sequence(AC自动机 + 矩阵快速幂)题解

    题意:给出m个模式串,要求你构造长度为n(n <= 2000000000)的主串,主串不包含模式串,问这样的主串有几个 思路:因为要不包含模式串,显然又是ac自动机.因为n很大,所以用dp不太好 ...

  10. POJ2778(SummerTrainingDay10-B AC自动机+矩阵快速幂)

    DNA Sequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 17160   Accepted: 6616 Des ...

随机推荐

  1. DotNetBar如何控制窗体样式

    在C#中使用控件DevComponents.DotNetBar时,如何创建一个漂亮的窗口,并控制窗体样式呢?   1.新建一个DotNetBar窗体             2.使OFFICE窗口风格 ...

  2. 8 -- 深入使用Spring -- 3...1 Resource实现类FileSystemResource

    8.3.1 Resource实现类------FileSystemResource:访问文件系统的资源的实现类 3.访问文件系统资源 Spring提供的FileSystemResource类用于访问文 ...

  3. 利用Visio绘制数据流图与组织结构图

    绘制数据流图: 利用Visio 2007来绘制网上书店系统的数据流图.利用Visio 2007创建Gane- Sarson数据流图,可以选择“软件和数据库”模板,然后再选择“数据流模型图”,创建之后可 ...

  4. SaltStack 批量安装软件

    这里我们用 SaltStack 服务端对多台客户端远程批量安装 httpd,步骤如下: [root@localhost ~]$ vim /etc/salt/master # 编辑配置文件,打开base ...

  5. iOS - 截屏,view截图的基本方法

    推荐一个第三方好用的框架:SDScreenshotCapture #define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice cur ...

  6. <转>13个实用的Linux find命令示例

    注:本文摘自青崖白鹿,翻译的妈咪,我找到了! -- 15个实用的Linux find命令示例, 感谢翻译的好文. 除了在一个目录结构下查找文件这种基本的操作,你还可以用find命令实现一些实用的操作, ...

  7. shell 脚本调试

    1.第一行加 -xv #!/bin/bash –xv 2. bash -x shellName 3.如果只想调试其中几行脚本的话可以用 set -x 和 set +x 把要调试的部分包含进来: 比如: ...

  8. Qt编写可拖动对象+背景地图+多种样式+多种状态(开源)

    在很多项目应用中,需要根据数据动态生成对象显示在地图上,比如地图标注,同时还需要可拖动对象到指定位置显示,能有多种状态指示,为此特意编写本控件,全部开源出来,欢迎大家提建议.同时多多支持整套自定义控件 ...

  9. 【本周主题】第一期:JavaScript单线程与异步

    相信下边这个图一定都不陌生,本周就围绕这张图深入了解下js代码执行时的来龙去脉. 一.JavaScript是单线程的 2018-11-19 21:21:21 周一 js本质是单线程的.这一特性是jav ...

  10. mvc 默认访问 Area 下控制器方法

    在MVC项目中经常会使用到Area来分开不同的模块让项目结构更加的清晰.如果想网站打开默打开Area下的控制器时会出现以下的错误 “/”应用程序中的服务器错误. 未找到视图“Index”或其母版视图, ...