题目大意:DNA序列是有 ATGC 组成的,现在知道一些动物的遗传片段有害的,那么如果给出这些有害的片段,能否求出来所有长度为 N 的基因中有多少是不包含这些有害片段的。
 
分析:也是断断续续做了一天,做这道题前先做一下 hdu2157 这道题,因为这道题的思路就是从它转变过来的,看明白了这个后,就需要构造一个矩阵,不过因为按照自己的想法构造的矩阵,一直WA,不明白为什么,后来发现是因为在子节点不存在时候查询后缀时候包含子节点的时候不彻底造成的,还是对AC自动机了解的不多。不过通过这题也学会了矩阵快速幂,算是不错的收获。
 
代码如下:
==========================================================================================================================
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std; const int MAXN = ;
const int MAXM = ;
const int mod = ; struct Matrix{long long edge[MAXN][MAXN];};
struct TrieNode
{
TrieNode *Fail, *next[MAXM];
int danger, Num;///节点编号,是否是危险指针
}; int GetVal(char ch)
{
if(ch == 'A')return ;
if(ch == 'T')return ;
if(ch == 'G')return ; return ;
}
void Insert(TrieNode *root, char s[], int &Num)
{
TrieNode *p = root; for(int i=; s[i]; i++)
{
int k = GetVal(s[i]); if(p->next[k] == NULL)
{
p->next[k] = new TrieNode();
p->next[k]->Num = ++Num;
}
p = p->next[k];
} p->danger = true;
}
void GetFail(TrieNode *root)
{
TrieNode *p = root, *temp;
queue<TrieNode *> Q; for(int i=; i<MAXM; i++)
{
if(p->next[i])
{
p->next[i]->Fail = root;
Q.push(p->next[i]);
}
} while(Q.size())
{
p = Q.front();
Q.pop(); for(int i=; i<MAXM; i++)if(p->next[i])
{
temp = p->Fail; while(temp != NULL)
{
if(temp->next[i] != NULL)
{
p->next[i]->Fail = temp->next[i];
///如果这个后缀是危险节点的话,那么向下传递一下
p->next[i]->danger |= temp->next[i]->danger; break;
} temp = temp->Fail;
} if(temp == NULL)
p->next[i]->Fail = root; Q.push(p->next[i]);
}
} root->Fail = root;
}
void GetMatrix(TrieNode *root, Matrix &Map)
{
TrieNode *p = root, *temp; if(p->danger)return ; for(int i=; i<MAXM; i++)
{
if(p->next[i])
GetMatrix(p->next[i], Map); temp = p;
///当p->next[i] 不存在时,访问它的后缀Fail,直到根节点停止
while(temp->Num != && !temp->next[i])
temp = temp->Fail; if(!temp->next[i])
{///如果在前后缀没有找到,那么就走向根节点处
Map.edge[p->Num][]++;
continue;
}
///如果这个点是危险节点
if(temp->next[i]->danger)continue; Map.edge[p->Num][temp->next[i]->Num]++;
}
}
void Mul(Matrix a, Matrix b, Matrix &ans, int len)
{
memset(ans.edge, , sizeof(ans.edge)); for(int i=; i<=len; i++)
for(int j=; j<=len; j++)
for(int k=; k<=len; k++)
{
ans.edge[i][j] += a.edge[i][k] * b.edge[k][j];
ans.edge[i][j] %= mod;
}
}
void QuickPow(Matrix Map, long long k, Matrix &ans, int len)
{
memset(ans.edge, , sizeof(ans.edge)); for(int i=; i<=len; i++)
ans.edge[i][i] = ; while(k)
{
if(k & )
Mul(ans, Map, ans, len);
Mul(Map, Map, Map, len); k /= ;
}
} void FreeTrie(TrieNode *root)
{
for(int i=; i<MAXM; i++)
{
if(root->next[i])
FreeTrie(root->next[i]);
} free(root);
} int main()
{
long long M, K; while(scanf("%lld%lld", &M, &K) != EOF)
{
char s[MAXN];
int num = ;
TrieNode *root = new TrieNode(); while(M--)
{
scanf("%s", s);
Insert(root, s, num);
} GetFail(root); Matrix Map, ans; memset(Map.edge, , sizeof(Map.edge)); GetMatrix(root, Map);
QuickPow(Map, K, ans, num); long long sum=; for(int i=; i<=num; i++)
{
sum = (sum + ans.edge[][i]) % mod;
} printf("%lld\n", sum); FreeTrie(root);
} return ;
}

DNA Sequence - POJ 2778(AC自动机+矩阵乘法)的更多相关文章

  1. DNA Sequence POJ - 2778 AC 自动机 矩阵乘法

    定义重载运算的时候一定要将矩阵初始化,因为这个调了一上午...... Code: #include<cstdio> #include<algorithm> #include&l ...

  2. 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 ...

  3. POJ 2778 (AC自动机+矩阵乘法)

    POJ 2778 DNA Sequence Problem : 给m个只含有(A,G,C,T)的模式串(m <= 10, len <=10), 询问所有长度为n的只含有(A,G,C,T)的 ...

  4. poj 2778 AC自动机+矩阵快速幂

    题目链接:https://vjudge.net/problem/POJ-2778 题意:输入n和m表示n个病毒,和一个长为m的字符串,里面只可以有'A','C','G','T' 这四个字符,现在问这个 ...

  5. 【bzoj1444】[Jsoi2009]有趣的游戏 AC自动机+矩阵乘法

    题目描述 输入 注意 是0<=P 输出 样例输入 样例输出 题解 AC自动机+矩阵乘法 先将所有字符串放到AC自动机中,求出Trie图. 然后构建邻接矩阵:如果x不是某个字符串的末位置,则x连向 ...

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

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

  7. 【poj2778-DNA Sequence】AC自动机+矩阵乘法

    题意: (只含AGCT)给定m个病毒串,让你构造一个长度为n的字符串(也只含有AGCT),问有多少种方案.n很大:1<=n<=2000000000 题解: 用病毒串建立AC自动机(num个 ...

  8. 【POJ2778】AC自动机+矩阵乘法

    DNA Sequence Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 14758 Accepted: 5716 Descrip ...

  9. [BZOJ 1009] [HNOI2008] GT考试 【AC自动机 + 矩阵乘法优化DP】

    题目链接:BZOJ - 1009 题目分析 题目要求求出不包含给定字符串的长度为 n 的字符串的数量. 既然这样,应该就是 KMP + DP ,用 f[i][j] 表示长度为 i ,匹配到模式串第 j ...

随机推荐

  1. Xcode4.4中,代码无法高亮、无法自动补全

    1.代码无法高亮显示:2.代码不能自动补全,或者给出提示建议:(当然这个补全的功能我在设置当中是打开的状态)3.新建一个项目,代码还是依然没有高亮显示,但是有补全功能:4.然后我就在网络上搜索了相关的 ...

  2. Python:标准数据类型6种

    #!/usr/bin/python3 #python的基本语法和数据类型 #python3中 一行有多个语句,用分号分割(;) print("aaa") ;print(" ...

  3. 通用方法解决dedecms导航调用二级、三级栏目菜单

    博客之前做网站的时候经常会遇到二级菜单.三级菜单.了解dede的人都知道从5.5版本开始都有二级菜单的调用方法了,网上也有不少的教程文章.不过这个调用需要修改dede源码的二级菜单样式.个人感觉不是很 ...

  4. phpcms v9 get调用标签整理

    常见的phpcms标签调用  1.调用本系统单条数据(调用ID为1的信息,标题长度不超过25个汉字,显示更新日期): "select * from phpcms_content where  ...

  5. 知识库总结mysql常用cmd命令

    打开命令目录 打开D盘mysql目录 d: cd D:\Ampps\mysql\bin 常用操作 将mysql目录下bin目录中的mysql.exe放到C:\WINDOWS下,可以执行以下命令 连接: ...

  6. Ubuntu14.02 Sublimte2安装

    $sudo add-apt-repository ppa:webupd8team/sublime-text-2 $sudo apt-get update $sudo apt-get install s ...

  7. 简单的贴图显示shander

    Shader "ztq/Diffuse" {    Properties {           _Color ("Main Color", Color) =  ...

  8. coroutine协程

    如果你接触过lua这种小巧的脚本语言,你就会经常接触到一个叫做协程的神奇概念.大多数脚本语言都有对协程不同程度的支持.但是大多编译语言,如C/C++,根本就不知道这样的东西存在.当然也很多人研究如何在 ...

  9. 开发人员应关注的20个jQuery网站/博客

    http://blog.jobbole.com/1466/ 2.  10个优秀的移动Web应用开发框架 http://blog.jobbole.com/1436/ 3.  介绍jQ Mobile ht ...

  10. [BZOJ 3110] [Zjoi2013] K大数查询 【树套树】

    题目链接: BZOJ - 3110 题目分析 这道题是一道树套树的典型题目,我们使用线段树套线段树,一层是区间线段树,一层是权值线段树.一般的思路是外层用区间线段树,内层用权值线段树,但是这样貌似会很 ...