DNA Sequence

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 11860   Accepted: 4527

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

  几个月没编AC自动机,突然编一下感觉之痛苦。

  主要问题一点是fail指针构造时没有即使break掉,另一点是tail标记上传时需要加入一个while循环。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXN 100
#define MAXT 100
#define MOD 100000
typedef long long qword; struct trie_node
{
int ptr[];
int fail;
char w;
bool tl;
}trie[MAXT];
int topt=;
char str[MAXN];
void Add_word(char *str)
{
int now=;
int ind;
while (*str)
{
ind=*(str++)-'A';
if (!trie[now].ptr[ind])
{
trie[now].ptr[ind]=++topt;
trie[topt].w=ind+'A';
trie[topt].tl=false;
}
now=trie[now].ptr[ind];
}
trie[now].tl=true;
}
int q[MAXN];
void Build_Ac()
{
int head=-,tail=;
int now,temp;
int i,j;
q[]=;
trie[].fail=;
while (head<tail)
{
now=q[++head];
for (i=;i<;i++)
{
if (!trie[now].ptr[i])continue;
q[++tail]=trie[now].ptr[i];
if (now==)
{
trie[trie[now].ptr[i]].fail=now;
continue;
}
temp=trie[now].fail;
while(temp!=)
{
if (trie[temp].ptr[i])
{
trie[trie[now].ptr[i]].fail=trie[temp].ptr[i];
break;
}
temp=trie[temp].fail;
}
if (!trie[trie[now].ptr[i]].fail)
trie[trie[now].ptr[i]].fail=trie[].ptr[i];
if (!trie[trie[now].ptr[i]].fail)
trie[trie[now].ptr[i]].fail=;
}
}
for (i=;i<=topt;i++)
{
for (j=;j<;j++)
{
if (!trie[i].ptr[j])
{
temp=trie[i].fail;
while (temp!=)
{
if (trie[temp].ptr[j])
{
trie[i].ptr[j]=trie[temp].ptr[j];
break;
}
temp=trie[temp].fail;
}
if (!trie[i].ptr[j])
trie[i].ptr[j]=trie[].ptr[j];
if (!trie[i].ptr[j])
trie[i].ptr[j]=;
}
}
}
j=;
while (j--)
{
for (i=;i<=tail;i++)
{
if (trie[trie[i].fail].tl)
trie[i].tl=true;
}
}
}
struct matrix
{
int n,m;
qword a[MAXN][MAXN];
matrix()
{
memset(a,,sizeof(a));
}
void pm()
{
int i,j;
for (i=;i<=n;i++)
{
for (j=;j<=m;j++)
{
printf("% 4d ",a[i][j]);
}
printf("\n");
}
printf("\n");
}
}m1,r1,m2;
matrix operator *(matrix &m1,matrix &m2)
{
if (m1.m!=m2.n)throw ;
matrix ret;
ret.n=m1.n;
ret.m=m2.m;
int i,j,k;
for (i=;i<=ret.n;i++)
{
for (j=;j<=ret.m;j++)
{
for (k=;k<=m1.m;k++)
{
ret.a[i][j]=(ret.a[i][j]+m1.a[i][k]*m2.a[k][j])%MOD;
}
}
}
return ret;
} int main()
{
freopen("input.txt","r",stdin);
// freopen("output.txt","w",stdout);
int n,m,i,j,k,x,y,z;
scanf("%d%d\n",&m,&n);
topt=;
trie[].w='#';
for (i=;i<m;i++)
{
scanf("%s",str);
x=strlen(str);
for (j=;j<x;j++)
{
switch(str[j])
{
case 'A':str[j]='A';break;
case 'G':str[j]='B';break;
case 'C':str[j]='C';break;
case 'T':str[j]='D';break;
}
}
Add_word(str);
}
Build_Ac();
m1.m=m1.n=topt;
for (i=;i<=topt;i++)
{
for (j=;j<;j++)
{
if (trie[trie[i].ptr[j]].tl)continue;
m1.a[trie[i].ptr[j]][i]++;
}
}
// m1.pm();
m2.m=,m2.n=topt;
m2.a[][]=;
while (n)
{
if (n&)
{
m2=m1*m2;
}
m1=m1*m1;
n>>=;
}
/*
for (i=1;i<=n;i++)
{
m2=m1*m2;
// m2.pm();
}*/
qword ans=;
for (i=;i<=topt;i++)
{
ans+=m2.a[i][];
ans%=MOD;
}
printf("%d\n",ans);
return ;
}

poj 2778 DNA Sequence AC自动机DP 矩阵优化的更多相关文章

  1. POJ 2778 DNA Sequence (AC自动机+DP+矩阵)

    题意:给定一些串,然后让你构造出一个长度为 m 的串,并且不包含以上串,问你有多少个. 析:很明显,如果 m 小的话 ,直接可以用DP来解决,但是 m 太大了,我们可以认为是在AC自动机图中,根据离散 ...

  2. POJ 2778 DNA Sequence ( AC自动机、Trie图、矩阵快速幂、DP )

    题意 : 给出一些病毒串,问你由ATGC构成的长度为 n 且不包含这些病毒串的个数有多少个 分析 : 这题搞了我真特么久啊,首先你需要知道的前置技能包括 AC自动机.构建Trie图.矩阵快速幂,其中矩 ...

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

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

  4. POJ 2778 DNA Sequence (AC自动机,矩阵乘法)

    题意:给定n个不能出现的模式串,给定一个长度m,要求长度为m的合法串有多少种. 思路:用AC自动机,利用AC自动机上的节点做矩阵乘法. #include<iostream> #includ ...

  5. poj 2778 DNA Sequence AC自动机

    DNA Sequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11860   Accepted: 4527 Des ...

  6. POJ 2778 DNA Sequence (AC自己主动机 + dp)

    DNA Sequence 题意:DNA的序列由ACTG四个字母组成,如今给定m个不可行的序列.问随机构成的长度为n的序列中.有多少种序列是可行的(仅仅要包括一个不可行序列便不可行).个数非常大.对10 ...

  7. [POJ2778]DNA Sequence(AC自动机 + DP + 矩阵优化)

    传送门 AC自动机加DP就不说了 注意到 m <= 10,所以模式串很少. 而 n 很大就需要 log 的算法,很容易想到矩阵. 但是该怎么构建? 还是矩阵 A(i,j) = ∑A(i,k) * ...

  8. POJ 3691 DNA repair(AC自动机+DP)

    题目链接 能AC还是很开心的...此题没有POJ2778那么难,那个题还需要矩阵乘法,两个题有点相似的. 做题之前,把2778代码重新看了一下,回忆一下当时做题的思路,回忆AC自动机是干嘛的... 状 ...

  9. HDU 2457/POJ 3691 DNA repair AC自动机+DP

    DNA repair Problem Description   Biologists finally invent techniques of repairing DNA that contains ...

随机推荐

  1. BZOJ 2754([SCOI2012]喵喵叫的星球-统计序列的后缀阵列中子序列出现次数)

    2754: [SCOI2012]喵喵叫的星球 Time Limit: 20 Sec  Memory Limit: 128 MB Submit: 805  Solved: 380 [id=2754&qu ...

  2. JavaScript中七种函数调用方式及对应 this 的含义

    this 在 JavaScript 开发中占有相当重要的地位,不过很多人对this这个东西都感觉到琢磨不透.要真正理解JavaScript的函数机制,就非常有必要搞清楚this到底是怎么回事. 函数调 ...

  3. TimeUnit(转)

    java.util.concurrent并发库是JDK1.5新增的,其作者是Doug Lea ,此人是个BOSS级别的天才人物了.有了他提供的类库,使得我们对多线程并发.锁有了很大的帮助,减少了并发难 ...

  4. 《Linux内核修炼之道》 系列

    http://blog.csdn.net/fudan_abc/article/category/655796

  5. careercup-链表 2.7

    2.7 编写一个函数,检查链表是否为回文. 思路:1)可以利用链表中的元素采用头插法创建一个新的链表,然后比较两个链表的元素是否相等.   2)利用快慢指针,将链表后半部分逆转之后,比较前半部分与后半 ...

  6. PureMVC(JS版)源码解析(一):观察者模式解析

          假设一种情景,在程序开发中,我们需要在某些数据变化时,其他的类做出相应,例如在游戏中,升级一件装备,会触发玩家金币数量改变,背包数据改变和冷却队列数据改变等等.我们不可能设置setInte ...

  7. Android 开发之动画详解

    一.动画类型 Android的animation由四种类型组成:alpha.scale.translate.rotate XML配置文件中 alpha 渐变透明度动画效果 scale 渐变尺寸伸缩动画 ...

  8. jQuery给CheckBox添加事件

    <asp:CheckBox ID="ckbTable" runat="server" Checked="false" /> &l ...

  9. 手机端的表单验证和PC端的不同

    1.手机端:由于页面小的局限性,表单验证从上到下依次进行,如果上一个验证不通过,则给出错误提示,代码中return回去,不必进行下一个的校验: 2.PC端:页面范围大,一般是在表单的后面或者下面,提示 ...

  10. arcgis engine - 添加图例,指北针.

    esri帮助提供了使用比例尺的方法: Working with map surrounds 主要代码为: public void AddMapSurround(IPageLayout pageLayo ...