题意:给出m个致病DNA片段,求长为n且不含致病片段的DNA序列共有多少种。

数据范围:0 <= m <= 10,1 <= n <=2000000000

这题初看起来与上一题差不多,但一看数据范围就傻了……

分析:先建m个致病DNA片段的自动机,然后求出自动机中结点之间转移的路径数目,这样就可以得到一个有向图,所求问题就变为从根结点出发,到达任意一点,所走路径长度为n且路径不经过危险结点的路径数目。再抽象一下,就是求一个边长均为1的有向图中2点之间长为n的路径数目,这就不难想到矩阵了。设G为邻接矩阵,则Gk中第i行j列的元素表示从i到j长为k的路径数目。

View Code

#include <stdio.h>
#include <string.h>
#include <queue>
using namespace std;
#define M 11
#define LEN 15
#define SIZE (M*LEN)
#define mod 100000typedef __int64 LL;int next[M*LEN][4];
int fail[M*LEN];
bool isend[M*LEN];
int m,n,node;
LL mat[M*LEN][M*LEN];
LL tmp[M*LEN][M*LEN];
LL ans[M*LEN][M*LEN];
void init()
{node=1;memset(next[0],0,sizeof(next[0]));
}
void add(int cur,int k)
{memset(next[node],0,sizeof(next[node]));isend[node]=0;next[cur][k]=node++;
}
int hash(char c)
{switch(c){case 'A':   return 0;case 'C':   return 1;case 'T':   return 2;case 'G':   return 3;}
}
void insert(char *s)
{int i,k,cur;for(i=cur=0;s[i];i++){k=hash(s[i]);if(!next[cur][k])   add(cur,k);cur=next[cur][k];}isend[cur]=1;
}
void build_ac()
{queue<int>q;int cur,nxt,tmp;fail[0]=0;q.push(0);while(!q.empty()){cur=q.front(),q.pop();for(int k=0;k<4;k++){nxt=next[cur][k];if(nxt){if(cur==0)  fail[nxt]=0;else{for(tmp=fail[cur];tmp && !next[tmp][k];tmp=next[tmp][k]);fail[nxt]=next[tmp][k];}if(isend[fail[nxt]]) isend[nxt]=1;q.push(nxt);}else{next[cur][k]=next[fail[cur]][k];}}}
}
void build_mat()
{int cur,nxt,k;memset(mat,0,sizeof(mat));for(cur=0;cur<node;cur++){if(isend[cur])  continue;for(k=0;k<4;k++){nxt=next[cur][k];if(!isend[nxt])  mat[cur][nxt]++;}}
}
void mat_mul(LL a[][SIZE],LL b[][SIZE])
{for(int i=0;i<node;i++){for(int j=0;j<node;j++){tmp[i][j]=0;for(int k=0;k<node;k++){tmp[i][j]+=a[i][k]*b[k][j];}tmp[i][j]%=mod;}}
}
void mat_pow(int k)
{memset(ans,0,sizeof(ans));for(int i=0;i<node;i++) ans[i][i]=1;while(k){if(k&1){mat_mul(ans,mat);memcpy(ans,tmp,sizeof(tmp));}k>>=1;mat_mul(mat,mat);memcpy(mat,tmp,sizeof(tmp));}
}
void solve()
{build_ac();build_mat();mat_pow(n);LL ret=0;for(int i=0;i<node;i++) ret+=ans[0][i];printf("%I64d\n",ret%mod);
}
int main()
{char s[LEN];while(~scanf("%d%d",&m,&n)){init();for(int i=0;i<m;i++){scanf("%s",s);insert(s);}solve();}return 0;
}

转载于:https://www.cnblogs.com/algorithms/archive/2012/08/08/2628813.html

POJ 2778 DNA Sequence (自动机DP+矩阵快速幂)相关推荐

  1. 【BZOJ】4861: [Beijing2017]魔法咒语 AC自动机+DP+矩阵快速幂

    [题意]给定n个原串和m个禁忌串,要求用原串集合能拼出的不含禁忌串且长度为L的串的数量.(60%)n,m<=50,L<=100.(40%)原串长度为1或2,L<=10^18. [算法 ...

  2. [BJOI2017]魔法咒语(AC自动机+DP+矩阵快速幂)

    文章目录 title solution code title solution 针对数据编程才是坠吊的!!! 观察数据,发现分隔数据的 L L L跨度过大,没有衔接--推测很有可能是分数据做法 ①:考 ...

  3. 第九届河南省赛 宣传墙 //状压dp+矩阵快速幂+dfs

    http://nyoj.top/problem/1273 状压dp+矩阵快速幂+dfs 1273-宣传墙 内存限制:64MB 时间限制:1000ms 特判: No 通过数:19 提交数:64 难度:4 ...

  4. Codeforces 621E Wet Shark and Block【dp + 矩阵快速幂】

    题意: 有b个blocks,每个blocks都有n个相同的0~9的数字,如果从第一个block选1,从第二个block选2,那么就构成12,问对于给定的n,b有多少种构成方案使最后模x的余数为k. 分 ...

  5. 【BZOJ】2553: [BeiJing2011]禁忌 AC自动机+期望+矩阵快速幂

    [题意]给定n个禁忌字符串和字符集大小alphabet,保证所有字符在集合内.一个字符串的禁忌伤害定义为分割能匹配到最多的禁忌字符串数量(一个可以匹配多次),求由字符集构成的长度为Len的字符串的期望 ...

  6. POJ 2778 DNA Sequence [AC自动机 + 矩阵快速幂]

    http://poj.org/problem?id=2778 题意:给一些只由ACGT组成的模式串,问有多少种长度为n且不含有给出的模式串的DNA序列. 自动机的状态转换可以看成一个有向图(有重边的) ...

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

    题目链接:点击查看 题目大意:给出 n 个长度不大于 10 的字符串表示病毒串,再给出一个长度 len ,问长度为 len 的字符串中,有多少个字符串不含有病毒串作为子串 题目分析:因为病毒串的长度和 ...

  8. POJ - 3613 Cow Relays(Floyd思想+矩阵快速幂+动态规划)

    题目链接:点击查看 题目大意:给定一张由T(T<=100)条边构成的无向图,点的编号为1~1000,之间的整数,求从起点S到终点E恰好经过N(N<=1e6)条边(可重复经过)的最短路 题目 ...

  9. BZOJ 2004 公交线路(状压DP+矩阵快速幂)

    注意到每个路线相邻车站的距离不超过K,也就是说我们可以对连续K个车站的状态进行状压. 然后状压DP一下,用矩阵快速幂加速运算即可. #include <stdio.h> #include ...

最新文章

  1. R语言获取当前R版本(version)实战
  2. iOS学习9_事件分发amp;响应链
  3. 俄罗斯机器人雄鹿_在雄鹿无球可打,在火箭重获新生!哈登,你又让一人打出身价...
  4. python中hashmap的方法_如何为Java的HashMap模拟Python的dict的“ items(...
  5. K8S精华问答 | CentOS下如何配置主机互信?
  6. Linux生成随机数字和字符串
  7. 【HDU5482】Numquam vincar,暴力(da biao)预处理+组合数
  8. 华为数据之道_数字化与数据治理的典范实践者 | 华为数据之道
  9. Spanning Tree Protocol介绍
  10. mock模拟的数据能增删改查吗_新课通知: React+Umi3+Typescript+Mock
  11. bboss_spring_struts2_myibatis对比分析
  12. 给Jquery easyui 的datagrid 每行添加操作链接
  13. outlook 表格使用技巧
  14. 接口没获取到就被使用_使用CompletableFuture时,那些令人头疼的问题
  15. nbu备份本机oracle,大话nbu九(nbu异机备份恢复oracle)
  16. java-清楚明了的集合
  17. 2023适老用品展、CISSE北京养老展、老年产业博览会
  18. php数字转换百千万,PHP数字金额转换成中文大写显示
  19. c++ 鼠标切换形状
  20. 硬件设计——MOS管实际应用详解

热门文章

  1. cart2pol函数
  2. 可简单图化算法(Havel算法)
  3. 多进程爬虫(爬取小说)Python实现
  4. 转载:ACL权限控制
  5. jQuery基础:下(事件及动画效果)
  6. lamda表达式 随机取数据的方法
  7. MVCWebForm对照学习:传值方式
  8. 天津政府应急系统之GIS一张图(arcgis api for flex)讲解(四)地图导航控件模块...
  9. 完美/兼容版添加事件以及删除事件
  10. 抛硬币 直到连续出现两次字为止