题目链接:http://poj.org/problem?id=2778

题意:有m种DNA序列是有疾病的,问有多少种长度为n的DNA序列不包含任何一种有疾病的DNA序列。(仅含A,T,C,G四个字符)

思路:Trie图的状态转移,用矩阵mat[i][j]来表示从结点i到j只走一步有几种走法,那么mat的n次幂就表示从结点i到j走n步有几种走法,题目要求解的就是从头节点走n步且不包含危险结点的走法。

mat = mat^n   ans = (mat[0][0] + mat[0][1] + ... + mat[0][num]) num为结点个数

code:

 #include <cstdio>
#include <cstring>
#include <queue>
#include <map>
using namespace std;
const int KIND = ;
const int MAXN = ;
const int MOD = ;
typedef long long LL; struct Trie
{
int next[MAXN][KIND], fail[MAXN];
bool isExit[MAXN];
int root, L;
map<char, int> mp;
LL mat[MAXN][MAXN];
LL ret[MAXN][MAXN];
LL tmp[MAXN][MAXN];
int create()
{
for (int i = ; i < KIND; ++i)
next[L][i] = -;
isExit[L++] = false;
return L - ;
}
void init()
{
L = ;
root = create();
mp['A'] = ;
mp['C'] = ;
mp['G'] = ;
mp['T'] = ;
memset(mat, , sizeof(mat));
memset(ret, , sizeof(ret));
}
void insert(char str[])
{
int now = root;
int len = strlen(str);
for (int i = ; i < len; ++i)
{
if (- == next[now][mp[str[i]]])
next[now][mp[str[i]]] = create();
now = next[now][mp[str[i]]];
}
isExit[now] = true;
}
void build()
{
queue<int>Q;
for (int i = ; i < KIND; ++i)
{
if (- == next[root][i])
next[root][i] = root;
else
{
fail[next[root][i]] = root;
Q.push(next[root][i]);
}
}
while (!Q.empty())
{
int now = Q.front();
Q.pop();
if (isExit[fail[now]])
isExit[now] = true;
for (int i = ; i < KIND; ++i)
{
if (- == next[now][i])
next[now][i] = next[fail[now]][i];
else
{
fail[next[now][i]] = next[fail[now]][i];
Q.push(next[now][i]);
}
}
}
}
void getMatrix()
{
for (int i = ; i < L; ++i)
{
for (int j = ; j < KIND; ++j)
{
if (!isExit[next[i][j]])
++mat[i][next[i][j]];
}
}
}
void matrixMul(LL mat1[MAXN][MAXN], LL mat2[MAXN][MAXN])
{
LL mat3[MAXN][MAXN];
for (int i = ; i < L; ++i)
{
for (int j = ; j < L; ++j)
{
mat3[i][j] = ;
for (int k = ; k < L; ++k)
mat3[i][j] = (mat3[i][j] + mat1[i][k] * mat2[k][j]) % MOD;
}
}
memcpy(mat1, mat3, sizeof(mat3));
}
void matrixQuickMod(LL n)
{
getMatrix();
for (int i = ; i < L; ++i)
{
ret[i][i] = ;
for (int j = ; j < L; ++j)
tmp[i][j] = mat[i][j];
}
while (n)
{
if (n & ) matrixMul(ret, tmp);
matrixMul(tmp, tmp);
n >>= ;
}
}
};
Trie ac;
char str[];
int main()
{
int m;
LL n;
while (scanf("%d %lld", &m, &n) != EOF)
{
ac.init();
for (int i = ; i < m; ++i)
{
scanf("%s", str);
ac.insert(str);
}
ac.build();
ac.matrixQuickMod(n);
int ans = ;
for (int i = ; i < ac.L; ++i)
ans = (ans + ac.ret[][i]) % MOD;
printf("%d\n", ans);
}
return ;
}

最新文章

  1. 3. web前端开发分享-css,js提高篇
  2. meta 详解,html5 meta 标签日常设置
  3. 理解tcp协议的3次握手和面向连接
  4. 关于OpenGL的绘制上下文
  5. Checkpoint--与lazy writer区别
  6. hessionproxy
  7. 【转载】非线性分析中的ansys跟踪显示
  8. Kooboo中主要的几个关键词中的关系
  9. 文本阴影:text-shadow
  10. HTTP断点续传(分块传输)(HTTP头格式非常清楚)
  11. C-Free 5.0编译失败问题解决办法
  12. 树莓派学习笔记——USB wifi配置指南
  13. ES6小点心第二弹——底部浮现弹窗
  14. Linux x86_64内核中断初始化
  15. 提高你的python:解释 yield 和 Generators(生成器)
  16. uni-app第三方登陆-微信
  17. struts2整合uploadify插件怎样传参数
  18. SET XACT_ABORT ON [SQL SERVER] 设置事务全部回滚
  19. Junit概述
  20. css 样式控制文本过长实现省略号

热门文章

  1. Microsoft Azure 大计算 – 宣布收购 GreenButton
  2. [LeetCode][Python]Longest Substring Without Repeating Characters
  3. mongodb remove删除文档的用法
  4. 框架计划随笔 三.EntityFramework在传统事务脚本模式下的使用
  5. Matlab中边缘提取方法简析
  6. 浅谈Mybatis(三)
  7. linux杂记(八)linux压缩与打包
  8. CSS3里面的高级属性
  9. Socket缓冲区探讨,是否有拆包的方式?
  10. 四轴飞行器1.2.3 STM32F407时钟配置和升级标准库文件