DNA Sequence - POJ 2778(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自动机+矩阵乘法)的更多相关文章
- DNA Sequence POJ - 2778 AC 自动机 矩阵乘法
定义重载运算的时候一定要将矩阵初始化,因为这个调了一上午...... Code: #include<cstdio> #include<algorithm> #include&l ...
- 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 ...
- POJ 2778 (AC自动机+矩阵乘法)
POJ 2778 DNA Sequence Problem : 给m个只含有(A,G,C,T)的模式串(m <= 10, len <=10), 询问所有长度为n的只含有(A,G,C,T)的 ...
- poj 2778 AC自动机+矩阵快速幂
题目链接:https://vjudge.net/problem/POJ-2778 题意:输入n和m表示n个病毒,和一个长为m的字符串,里面只可以有'A','C','G','T' 这四个字符,现在问这个 ...
- 【bzoj1444】[Jsoi2009]有趣的游戏 AC自动机+矩阵乘法
题目描述 输入 注意 是0<=P 输出 样例输入 样例输出 题解 AC自动机+矩阵乘法 先将所有字符串放到AC自动机中,求出Trie图. 然后构建邻接矩阵:如果x不是某个字符串的末位置,则x连向 ...
- POJ 2778 DNA Sequence (AC自动机,矩阵乘法)
题意:给定n个不能出现的模式串,给定一个长度m,要求长度为m的合法串有多少种. 思路:用AC自动机,利用AC自动机上的节点做矩阵乘法. #include<iostream> #includ ...
- 【poj2778-DNA Sequence】AC自动机+矩阵乘法
题意: (只含AGCT)给定m个病毒串,让你构造一个长度为n的字符串(也只含有AGCT),问有多少种方案.n很大:1<=n<=2000000000 题解: 用病毒串建立AC自动机(num个 ...
- 【POJ2778】AC自动机+矩阵乘法
DNA Sequence Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 14758 Accepted: 5716 Descrip ...
- [BZOJ 1009] [HNOI2008] GT考试 【AC自动机 + 矩阵乘法优化DP】
题目链接:BZOJ - 1009 题目分析 题目要求求出不包含给定字符串的长度为 n 的字符串的数量. 既然这样,应该就是 KMP + DP ,用 f[i][j] 表示长度为 i ,匹配到模式串第 j ...
随机推荐
- POJ 2186.Popular Cows (强连通)
强连通缩点,统计入度为1的缩点后的点的个数 个数1的话输出这个强连通分量的点的数量 否则输出0: code /* Kosaraju算法,无向图的强连通分量,时间复杂度O(n+m) 思路: 按照图G的深 ...
- jQuery慢慢啃之属性(三)
1.attr(name|properties|key,value|fn)设置或返回被选元素的属性值. $("img").attr("src");//获取属性 $ ...
- 浅谈Chrome V8引擎中的垃圾回收机制
垃圾回收器 JavaScript的垃圾回收器 JavaScript使用垃圾回收机制来自动管理内存.垃圾回收是一把双刃剑,其好处是可以大幅简化程序的内存管理代码,降低程序员的负担,减少因 长时间运转而带 ...
- DataNode工作原理(四)
DataNode的作用:提供真实文件数据的存储服务.以文件块进行存储. 文件块(block):最基本的存储单位.对文件内容而言,一个文件的长度大小是size,那么从文件的0偏移开始,按照固定的大小,顺 ...
- Python字符编码讲解
声明:本文参考 Python字符编码详解 在计算机中我们不管用什么语言和程序,最终数据在计算机中的都是字节码(也就是01形式)的形式存在的,如果 计算机直接把字节码显示在屏幕上,很明显一般人看不懂字节 ...
- Python模块解析之SocketServer(三)——模块思想
SocketServer 体系 由两个部分构成 BaseServer 和 BaseRequestHandler.思想很简单 BaseServer接受请求,将请求交给BaseReques ...
- PHP与MYSQL配合完成IP的存取
如何存储IP 程序设计要在功能实现的基础上最大限度的优化性能.而数据库设计是程序设计中不可忽略的重要部分,巧存IP地址可以一定程度提升性能. 利用函数算法处理 MySQL没有直接提供IP类型字段,但有 ...
- bt种子文件文件结构
估计80%以上接触互联网的人都知道bt是什么东西,任何一个用bt下载的人都知道这样一个概念,种子.bt种子就是记录了p2p对等网络中tracker, nodes, files等信息,也就是说,这个 ...
- BZOJ 1033 杀蚂蚁
Description 最近,佳佳迷上了一款好玩的小游戏:antbuster.游戏规则非常简单:在一张地图上,左上角是蚂蚁窝,右下角是蛋糕,蚂蚁会源源不断地从窝里爬出来,试图把蛋糕搬回蚂蚁窝.而你的任 ...
- [BZOJ 3626] [LNOI2014] LCA 【树链剖分 + 离线 + 差分询问】
题目链接: BZOJ - 3626 题目分析 考虑这样的等价问题,如果我们把一个点 x 到 Root 的路径上每个点的权值赋为 1 ,其余点的权值为 0,那么从 LCA(x, y) 的 Depth 就 ...