题意 : 给出一些病毒串,问你由ATGC构成的长度为 n 且不包含这些病毒串的个数有多少个

分析:

我们先分析Tire 图的结构 : Trie图是在AC自动机的原型上增添边使得状态可以快速转移,标记危险的节点(后缀是不良单词的节点); 那我们是想构造长度是n不包含不良串对不对 , 那是不是在trie图上从0节点走n步到安全节点的方案数(Trie图也是状态转移图)

在一个有向图中,A走k步到B的方案数(这显然是经典的矩阵快速幂问题),(原理需要自己搜索)先对原图建立一个邻接表M[i][j] , M[i][j] =1表示i到j有边直接相连,然后ans=pow(M,k)  ,ans[A][B] 为答案

#include<queue>
#include<stdio.h>
#include<string.h>
using namespace std; const int Max_Tot = 1e2 + ;
const int Letter = ;
const int MOD = 1e5;
int maxn;
int mp[]; struct mat{ int m[][]; }unit, M; mat operator * (mat a, mat b)
{
mat ret;
long long x;
for(int i=; i<maxn; i++){
for(int j=; j<maxn; j++){
x = ;
for(int k=; k<maxn; k++){
x += (long long)a.m[i][k]*b.m[k][j];
}
ret.m[i][j] = x % MOD;
}
}
return ret;
} inline void init_unit() { for(int i=; i<maxn; i++) unit.m[i][i] = ; } mat pow_mat(mat a, int n)
{
mat ret = unit;
while(n){
if(n&) ret = ret * a;
a = a*a;
n >>= ;
}
return ret;
} struct Aho{
struct StateTable{
int Next[Letter];
int fail, flag;
}Node[Max_Tot];
int Size;
queue<int> que; inline void init(){
while(!que.empty()) que.pop();
memset(Node[].Next, , sizeof(Node[].Next));
Node[].fail = Node[].flag = ;
Size = ;
} inline void insert(char *s){
int now = ;
for(int i=; s[i]; i++){
int idx = mp[s[i]];
if(!Node[now].Next[idx]){
memset(Node[Size].Next, , sizeof(Node[Size].Next));
Node[Size].fail = Node[Size].flag = ;
Node[now].Next[idx] = Size++;
}
now = Node[now].Next[idx];
}
Node[now].flag = ;
} //1) 如果son[i]不存在,将它指向 当前结点now的fail指针指
//向结点的i号后继(保证一定已经计算出来)。 //2) 如果son[i]存在,将它的fail指针指向 当前结点now的fail
//指针指向结点的i号后继(保证一定已经计算出来)。
inline void BuildFail(){
Node[].fail = ;
for(int i=; i<Letter; i++){
if(Node[].Next[i]){
Node[Node[].Next[i]].fail = ;
que.push(Node[].Next[i]);
}else Node[].Next[i] = ;///必定指向根节点
}
while(!que.empty()){
int top = que.front(); que.pop();
if(Node[Node[top].fail].flag) Node[top].flag = ;
for(int i=; i<Letter; i++){
int &v = Node[top].Next[i];
if(v){
que.push(v);
Node[v].fail = Node[Node[top].fail].Next[i];
}else v = Node[Node[top].fail].Next[i];
}
}
} inline void BuildMatrix(){
for(int i=; i<Size; i++)
for(int j=; j<Size; j++)
M.m[i][j] = ;
for(int i=; i<Size; i++){
for(int j=; j<Letter; j++){
if(!Node[i].flag && !Node[ Node[i].Next[j] ].flag)
M.m[i][Node[i].Next[j]]++;
}
}
maxn = Size;
} }ac; char S[];
int main(void)
{
mp['A']=,
mp['T']=,
mp['G']=,
mp['C']=;
int n, m;
while(~scanf("%d %d", &m, &n)){
ac.init();
for(int i=; i<m; i++){
scanf("%s", S);
ac.insert(S);
}
ac.BuildFail();
ac.BuildMatrix();
// for(int i=0; i<10; i++){
// for(int j=0; j<10; j++){
// printf("%d ", M.m[i][j]);
// }puts("");
// }puts(""); init_unit();
M = pow_mat(M, n); // for(int i=0; i<10; i++){
// for(int j=0; j<10; j++){
// printf("%d ", M.m[i][j]);
// }puts("");
// }puts(""); int ans = ;
for(int i=; i<ac.Size; i++)
ans += M.m[][i];
ans %= MOD;
printf("%d\n", ans);
}
return ;
}

POJ 2778 DNA Sequence ( Trie图、矩阵快速幂 )的更多相关文章

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

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

  2. POJ - 2778 ~ HDU - 2243 AC自动机+矩阵快速幂

    这两题属于AC自动机的第二种套路通过矩阵快速幂求方案数. 题意:给m个病毒字符串,问长度为n的DNA片段有多少种没有包含病毒串的. 根据AC自动机的tire图,我们可以获得一个可达矩阵. 关于这题的t ...

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

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

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

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

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

  6. poj 2778 AC自己主动机 + 矩阵高速幂

    // poj 2778 AC自己主动机 + 矩阵高速幂 // // 题目链接: // // http://poj.org/problem?id=2778 // // 解题思路: // // 建立AC自 ...

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

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

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

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

    题目:传送门 题意: 给你m个病毒串,只由(A.G.T.C) 组成, 问你生成一个长度为 n 的 只由 A.C.T.G 构成的,不包含病毒串的序列的方案数. 解: 对 m 个病毒串,建 AC 自动机, ...

随机推荐

  1. PythonDay15

    第十五章装饰器_递归 今日内容 带参数装饰器 多个装饰器修饰一个函数 递归 带参数的装饰器 # 判断argv,当登录不同的网页,会有不同的装饰效果def auth(argv):   def warpp ...

  2. 在Vue项目中加载krpano全景图

    在Vue-cli项目中做krpano全景图编辑器的时候,由于js插件的路径是动态的,做的过程中遇到了加载不到资源的难题,在网上搜索了好久也没找到合适的办法,最后想到了可能是JS加载的问题,于是解决了问 ...

  3. P4868 Preprefix sum

    传送门 挺显然的一题?单点修改,前缀和数组前缀查询 树状数组就可以维护了 考虑每个位置对应询问的贡献,设询问的位置为 $x$,对于原数组 $a[i]$ 的某个位置 $i$,它会贡献 $(x-i+1)* ...

  4. 不用再去找rem了,你想要的rem都在这

    一.兼容性. 目前,IE9+,Firefox.Chrome.Safari.Opera 的主流版本都支持了rem(大胆用吧,目前几乎所有手机浏览器都支持rem) 二.什么是rem. rem是相对于根元素 ...

  5. redis之使用场景

    随着数据量的增长,MySQL 已经满足不了大型互联网类应用的需求.因此,Redis 基于内存存储数据,可以极大的提高查询性能,对产品在架构上很好的补充.在某些场景下,可以充分的利用 Redis 的特性 ...

  6. css 文本单行显示溢出时出现省略号 多行显示溢出时出现省略号 首行缩进

    一.文本单行显示溢出时出现省略号 二.文本多行显示溢出时出现省略号(这种样式只能在webkit和移动端使用,包括小程序,不能设置固定高度) 三.首行缩进两字符 text-indent: 2em; 四. ...

  7. 22_3mybaits——连接池

    1.连接池 我们在实际开发中都会使用连接池. 因为它可以减少我们获取连接所消耗的时间. 2.mybatis中的连接池 mybatis连接池提供了3种方式的配置: 配置的位置: 主配置文件SqlMapC ...

  8. 批量修改zencart型号:品牌名称+型号格式

    批量修改zencart型号:品牌名称+型号格式 将下面代码保存为zc_change_model.php,上传到网站根目录运行即可,操作前先备份数据库 <?php /*** 批量修改zencart ...

  9. java modCount和fail-fast

    在迭代遍历线程不安全的集合的时候,如ArrayList,如果其他线程修改了该集合,那么将抛出ConcurrentModificationException,这就是 fail-fast 策略. modC ...

  10. PHP三种字符串界定符的区别(单引号,双引号,<<<)

      单引号,双引号,<<<的区别如下: 前续:今天突然遇到了<<<EOT,可在运行的时候出错了,所以就度娘了下. 1.单引号:’a string’  \’是唯一的转 ...