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 ...
随机推荐
- padding and margin.
padding is the space between the content and the border, whereas margin is the space outside the bor ...
- awk中split函数的用法
time='12:34:56' echo $time | awk '{split($0,a,":" ); print a[1]}' 12 echo $time | awk '{sp ...
- Typescript 团队合作的利器
前言 在介绍Typescript 之前,我需要隆重介绍一个人: 安德斯·海尔斯伯格(Anders Hejlsberg,1960.12~),丹麦人,Turbo Pascal编译器的主要作者,Delphi ...
- NSDate和NSString的转换及判定是昨天,今天,明天
用于uidate,picker.. +(NSDate*) convertDateFromString:(NSString*)uiDate{ NSDateFormatter *formatter ...
- 【转】 KVC/KVO原理详解及编程指南
原文地址:http://blog.csdn.net/wzzvictory/article/details/9674431 前言: 1.本文基本不讲KVC/KVO的用法,只结合网上的资料说说对这种技术的 ...
- IOS开发效率之为Xcode添加常用的代码片段
IOS开发效率之为Xcode添加常用的代码片段 原文地址:http://blog.csdn.net/pingchangtan367/article/details/30041285 tableview ...
- vs里 .sln和.suo 文件
Net解决方案下 .sln文件和.suo文件的解释:When a Web site is created, a solution file (.sln) and a hidden solution u ...
- Vijos1834 NOI2005 瑰丽华尔兹 动态规划 单调双端队列优化
设dp[t][x][y]表示处理完前t个时间段,钢琴停留在(x,y)处,最多可以走多少个格子 转移时只需逆着当前倾斜的方向统计len个格子(len为时间区间的长度,len=t-s+1),如果遇到障碍就 ...
- WebDriverWait 中 and, or, not用法
1. And 用法 wait.until(ExpectedConditions.and( ExpectedConditions.visibilityOfAllElementsLocatedBy(By. ...
- overflow第一次觉得你有点可恶
今天用css做下拉菜单,因为不需要做手机自适应,再手机里看起来工整一点就行,可是列表中最后一个li的宽度撑开了父div,导致看起来很糟糕,所以给父元素加overflow:hidden:但是下拉列表也被 ...