先使用AC自动机求得状态转移关系,再建立矩阵,mat[i][j]表示一步可从i到j且i,j节点均非终止字符的方案数,则此矩阵的n次方表示n步从i,到j的方法数。

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std; typedef long long LL;
const int N = 500, CH = 4;
struct Trie{
Trie *next[CH];
Trie *fail;
int cnt, id;
}tree[N]; int Hash[128];
bool flag[1008];
int chi[108][4]; const LL MOD = 100000;
int num;
struct Mat{
LL mat[108][108]; Mat(){
for(int i = 0; i <= num; i++){
for(int j = 0; j <= num; j++){
mat[i][j] = 0;
}
}
}
Mat operator*(const Mat &b){
Mat res;
for(int i = 0;i <= num; i++){
for(int j = 0; j <= num; j++){
for(int k = 0; k <= num; k++){
if(mat[i][k] == 0 || b.mat[k][j] == 0){
continue;
}
res.mat[i][j] += (mat[i][k] * b.mat[k][j])%MOD;
}
res.mat[i][j] %= MOD;
}
}
return res;
}
Mat operator^(LL k){
Mat res;
Mat a = *this;
for(int i = 0; i <= num; i++){
res.mat[i][i] = 1;
}
while(k){
if(k%2){
res = res * a;
}
a = a * a;
k /= 2;;
}
return res;
}
}; class ACauto{
public:
int nxt;
Trie *root; ACauto(){
root = &tree[0];
nxt=0;
memset(&tree[0], 0, sizeof(Trie));
} void insert(char *s){
Trie *p = root;
for(int i = 0; s[i]; i++){
int c = Hash[s[i]];
if(!p -> next[c]){
memset(&tree[++nxt], 0, sizeof(Trie));
p -> next[c] = &tree[nxt];
p -> next[c] -> id = nxt;
}
p = p -> next[c];
}
p -> cnt++;
flag[p -> id] = 1;
} void build(){
queue<Trie *> q;
q.push(root);
root -> fail = NULL;
while(!q.empty()){
Trie *cur = q.front();
q.pop();
//是否为终止结点
if(cur ->fail && cur != root && flag[cur->fail->id]){
flag[cur->id] = 1;
} for(int i = 0; i < CH; i++){
Trie *son = cur -> next[i];
Trie *tp = (cur == root)? root: cur -> fail->next[i];
if(son == NULL){
cur -> next[i] = tp;
}else{
son -> fail = tp;
q.push(son);
}
son = cur -> next[i];
//儿子节点
chi[cur -> id][i] = son -> id;
}
}
} }; char str[1008];
int main(){
Hash['A'] = 0;
Hash['C'] = 1;
Hash['G'] = 2;
Hash['T'] = 3;
int m;
LL n;
while(~scanf("%d %I64d", &m, &n)){
ACauto ac;
memset(flag, 0, sizeof(flag));
memset(chi, -1, sizeof(chi));
for(int i = 0; i < m; i++){
scanf("%s", str);
ac.insert(str);
}
ac.build();
num = ac.nxt;
Mat mt;
//mat[i][j]表示一步可从i到j且i,j节点均非终止字符的方案数
for(int i = 0; i <= num ; i++){
for(int j = 0; j < 4; j++){
if(flag[chi[i][j]] == 0){
mt.mat[i][chi[i][j]]++;
}
}
}
mt = mt ^ n;
LL res = 0;
for(int i = 0; i <= num; i++){
res = (res + mt.mat[0][i]) % MOD;
}
printf("%I64d\n", res); }
return 0;
}

  

POJ2778 DNA Sequence(AC自动机 矩阵)的更多相关文章

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

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

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

  3. POJ2278 DNA Sequence —— AC自动机 + 矩阵优化

    题目链接:https://vjudge.net/problem/POJ-2778 DNA Sequence Time Limit: 1000MS   Memory Limit: 65536K Tota ...

  4. 【距离GDOI:128天】【POJ2778】DNA Sequence(AC自动机+矩阵加速)

    已经128天了?怎么觉得上次倒计时150天的日子还很近啊 ....好吧为了把AC自动机搞透我也是蛮拼的..把1030和这道题对比了无数遍...最终结论是...无视时间复杂度,1030可以用这种写法解. ...

  5. [poj2778 DNA Sequence]AC自动机,矩阵快速幂

    题意:给一些字符串的集合S和整数n,求满足 长度为n 只含charset = {'A'.'T‘.'G'.'C'}包含的字符 不包含S中任一字符串 的字符串的种类数. 思路:首先对S建立ac自动机,考虑 ...

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

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

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

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

  8. poj 2778 DNA Sequence AC自动机DP 矩阵优化

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

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

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

随机推荐

  1. 如何用phpstorm编辑远程项目

    背景介绍:LAMP开发是很多公司喜欢采用的技术组合,故而做php开发,使用linux环境也是很多公司的要求.本文就来介绍下如何在windows下,使用phpstorm集成开发环境,来开发放在linux ...

  2. PE355

    似乎我和lyx讨论过这题..? LP可解决..(~0.8s)

  3. ubuntu查看端口占用

    查看端口号 sudo netstat -ltnp | 结束进程 sudo kill pid

  4. ubuntu14.04 archive sources.list

    deb http://archive.ubuntu.com/ubuntu/ trusty main restricted universe multiverse deb http://archive. ...

  5. ODATA 云驱动 http://www.cdata.com/cloud/

    ODATA 云驱动   http://www.cdata.com/cloud/    目前支持:ORACLE.MS SQL . MYSQL. -------------- rssbus      ht ...

  6. POJ 1330

    http://poj.org/problem?id=1330 题意:给你一棵树的上的两个点,要你求这两个点的最近的父亲节点. 第一行的是m案例数 第二行给你个N,代表有N-1种父子关系,其中a b,a ...

  7. linux自动定时备份web程序和mysql数据库

    前些天受朋友说linux定时备份不知道怎么搞,叫帮忙处理一下.由于这段时间正闲着,所以也就欣然答应.由于朋友对linux不懂也希望我将操作的过程记录下来,也就是越详细越好.所以写得比较$%^& ...

  8. ios 使用xib时,在UIScrollView中添建内容view时,使用约束的注意

    请参与一下链接:http://segmentfault.com/a/1190000002462033 简单的说下,就是必须写满一个view的6个约束,就是上下左右高宽,让scrollview 能够根据 ...

  9. cmd命令查看局域网内计算机信息

    ping [计算机名] ping -a [IP] nbtstat -a [IP] net view arp -a nslookup www.baidu.com 查看当前dns地址 tracert [I ...

  10. HDU 4873 ZCC Loves Intersection(JAVA、大数、推公式)

    在一个D维空间,只有整点,点的每个维度的值是0~n-1 .现每秒生成D条线段,第i条线段与第i维度的轴平行.问D条线段的相交期望. 生成线段[a1,a2]的方法(假设该线段为第i条,即与第i维度的轴平 ...