poj2778 DNA Sequence【AC自动机】【矩阵快速幂】
| Time Limit: 1000MS | Memory Limit: 65536K | |
| Total Submissions: 19991 | Accepted: 7603 |
Description
Suppose that DNA sequences of a species is a sequence that consist of A, C, T and G,and the length of sequences is a given integer n.
Input
Next m lines each line contain a DNA genetic disease segment, and length of these segments is not larger than 10.
Output
Sample Input
4 3
AT
AC
AG
AA
Sample Output
36
Source
题意:
给定m个致病基因序列。问长度为n的DNA序列中有多少个是没有这些序列的。
思路:
这道题用到AC自动机的状态转移的性质了。
当我建好了状态图之后,在某一个状态a时,我可以知道他可以到达的所有状态。Trie树上的一个节点就是一个状态。
初始矩阵mat[i][j]表示的是从状态i走一步到状态j有几种可能。使用矩阵快速幂,对这个矩阵做n次幂,就可以得到每个两个状态之间走n次总共有多少方案。
对于一个长为n的串,没有任何一个致病基因序列,那么所有致病基因转移过去的状态都不能算进去。
我们给每一个致病基因做一个危险标记,同时要注意所有fail可以到达的节点如果是danger的,他自己也要变成danger
因为这段致病基因作为后缀出现在这个串中了。
#include <iostream>
#include <set>
#include <cmath>
#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
//#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
#define inf 0x7f7f7f7f int m, n;
const int maxn = ;
const int maxlen = 2e6 + ; struct Matrix
{
unsigned long long mat[][];
int n;
Matrix(){}
Matrix(int _n)
{
n=_n;
for(int i=;i<n;i++)
for(int j=;j<n;j++)
mat[i][j] = ;
}
Matrix operator *(const Matrix &b)const
{
Matrix ret = Matrix(n);
for(int i=;i<n;i++)
for(int j=;j<n;j++)
for(int k=;k<n;k++)
ret.mat[i][j]+=mat[i][k]*b.mat[k][j] % ;
return ret;
}
void print()
{
for(int i = ; i < n; i++){
for(int j = ; j < n; j++){
printf("%d ", mat[i][j]);
}
printf("\n");
}
}
}; unsigned long long pow_m(unsigned long long a, int n)
{
unsigned long long ret = ;
unsigned long long tmp = a;
while(n){
if(n & )ret *= tmp;
tmp *= tmp;
n >>= ;
}
return ret;
} Matrix pow_M(Matrix a, int n)
{
Matrix ret = Matrix(a.n);
for(int i = ; i < a.n; i++){
ret.mat[i][i] = ;
}
Matrix tmp = a;
//cout<<a.n<<endl;
while(n){
if(n & )ret = ret * tmp;
tmp = tmp * tmp;
n >>= ;
//ret.print();
//cout<<endl;
}
return ret;
} struct tree{
int fail;
int son[];
bool danger;
}AC[maxlen];
int tot = , id[];
char s[]; void build(char s[])
{
int len = strlen(s);
int now = ;
for(int i = ; i < len; i++){
int x = id[s[i]];
if(AC[now].son[x] == ){
AC[now].son[x] = ++tot;
}
now = AC[now].son[x];
}
AC[now].danger = true;
} void get_fail()
{
queue<int>que;
for(int i = ; i < ; i++){
if(AC[].son[i] != ){
AC[AC[].son[i]].fail = ;
que.push(AC[].son[i]);
}
}
while(!que.empty()){
int u = que.front();
que.pop();
for(int i = ; i < ; i++){
if(AC[u].son[i] != ){
AC[AC[u].son[i]].fail = AC[AC[u].fail].son[i];
que.push(AC[u].son[i]);
}
else{
AC[u].son[i] = AC[AC[u].fail].son[i];
}
int x = AC[AC[u].son[i]].fail;
if(AC[x].danger){
AC[AC[u].son[i]].danger = true;
}
}
}
} /*int AC_query(char s[])
{
int len = strlen(s);
int now = 0, cnt = 0;
for(int i = 0; i < len; i++){
int x = id[s[i]];
now = AC[now].son[x];
for(int t = now; t; t = AC[t].fail){
if(!AC[t].vis && AC[t].ed != 0){
cnt++;
AC[t].vis = true;
}
}
}
return cnt;
}*/ Matrix getMatrix()
{
Matrix ret = Matrix(tot + );
//int now = 0;
for(int i = ; i < tot + ; i++){
if(AC[i].danger)continue;
for(int j = ; j < ; j++){
if(AC[AC[i].son[j]].danger == false){
ret.mat[i][AC[i].son[j]]++;
}
}
}
for(int i = ; i < tot + ; i++){
ret.mat[i][tot] = ;
}
return ret;
} int main()
{
id['A'] = ;id['T'] = ;id['C'] = ;id['G'] = ;
//cout<<1<<endl;
while(~scanf("%d%d", &m, &n)){
for(int i = ; i <= tot; i++){
AC[i].fail = ;
AC[i].danger = false;
for(int j = ; j < ; j++){
AC[i].son[j] = ;
}
}
tot = ;
for(int i = ; i <= m; i++){
scanf("%s", s);
build(s);
}
AC[].fail = ;
get_fail();
Matrix mmm = Matrix(tot + );
//int now = 0;
for(int i = ; i < tot + ; i++){
if(AC[i].danger)continue;
for(int j = ; j < ; j++){
if(AC[AC[i].son[j]].danger == false){
mmm.mat[i][AC[i].son[j]]++;
}
}
} mmm = pow_M(mmm, n);
unsigned long long res = ;
for(int i = ; i < mmm.n; i++){
res = (res + mmm.mat[][i]) % ;
} printf("%lld\n", res);
}
//getchar();
return ;
}
poj2778 DNA Sequence【AC自动机】【矩阵快速幂】的更多相关文章
- [poj2778]DNA Sequence(AC自动机+矩阵快速幂)
题意:有m种DNA序列是有疾病的,问有多少种长度为n的DNA序列不包含任何一种有疾病的DNA序列.(仅含A,T,C,G四个字符) 解题关键:AC自动机,实际上就是一个状态转移图,注意能少取模就少取模, ...
- 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 ...
- poj 2778 DNA Sequence ac自动机+矩阵快速幂
链接:http://poj.org/problem?id=2778 题意:给定不超过10串,每串长度不超过10的灾难基因:问在之后给定的长度不超过2e9的基因长度中不包含灾难基因的基因有多少中? DN ...
- poj2778DNA Sequence (AC自动机+矩阵快速幂)
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud DNA Sequence Time Limit: 1000MS Memory ...
- POJ2778 DNA Sequence(AC自动机 矩阵)
先使用AC自动机求得状态转移关系,再建立矩阵,mat[i][j]表示一步可从i到j且i,j节点均非终止字符的方案数,则此矩阵的n次方表示n步从i,到j的方法数. #include<cstdio& ...
- POJ2778 DNA Sequence(AC自动机+矩阵快速幂)
题目给m个病毒串,问不包含病毒串的长度n的DNA片段有几个. 感觉这题好神,看了好久的题解. 所有病毒串构造一个AC自动机,这个AC自动机可以看作一张有向图,图上的每个顶点就是Trie树上的结点,每个 ...
- 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 ...
- 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 DNA Sequence(AC自动机 + 矩阵快速幂)题解
题意:给出m个模式串,要求你构造长度为n(n <= 2000000000)的主串,主串不包含模式串,问这样的主串有几个 思路:因为要不包含模式串,显然又是ac自动机.因为n很大,所以用dp不太好 ...
- POJ2778(SummerTrainingDay10-B AC自动机+矩阵快速幂)
DNA Sequence Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 17160 Accepted: 6616 Des ...
随机推荐
- 字符编码笔记:ASCII,Unicode 和 UTF-8
http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html
- MTK 时区修改
1.修改packages/apps/Settings/res/xml-xx-xx/timezones.xml (xx-xx表示不同的语言和区域),添加下面的内容: <!-- timezo ...
- ios利用Reachability确认网络环境3G/WIFI(转)
iPhone开发技巧之网络篇(4)--- 确认网络环境 开发Web等网络应用程序的时候,需要确认网络环境,连接情况等信息.如果没有处理它们,是不会通过Apple的审查的. Apple 的 例程 Re ...
- SpringMVC -- 梗概--源码--壹--收参
附:实体类 Class : User package com.c61.entity; import java.text.SimpleDateFormat; import java.util.Date; ...
- CentOS7图形界面启动报错unable to connect to X server
以前还可以正常启动图形界面,这次启动失败,报错unable to connect to X server 使用的是oracle用户,因为我是在oracle用户下创建的oracle数据库等 解决办法: ...
- u3d 加密资源并缓存加载
// C# Example // Builds an asset bundle from the selected objects in the project view. // Once compi ...
- Android Studio 修改Logcat的颜色
在Android Studio里面默认的logcat显示颜色是灰色的,不同等级的log是没有颜色分别的,如图 这一点远不如Eclipse好看,但是Android Studio的logcat的颜色其实也 ...
- codeforces水题100道 第十八题 Codeforces Round #289 (Div. 2, ACM ICPC Rules) A. Maximum in Table (brute force)
题目链接:http://www.codeforces.com/problemset/problem/509/A题意:f[i][1]=f[1][i]=1,f[i][j]=f[i-1][j]+f[i][j ...
- PHP文件包含漏洞攻防实战
本文对PHP文件包含漏洞的形成.利用技巧及防范进行了详细分析,并通过一个真实案例演示了如何利用PHP文件包含漏洞对目标网站进行渗透测试,最终成功获取到网站的WebShell. PHP是一种非常流行的W ...
- sklearn 中的 Pipeline 机制 和FeatureUnion
一.pipeline的用法 pipeline可以用于把多个estimators级联成一个estimator,这么 做的原因是考虑了数据处理过程中一系列前后相继的固定流程,比如feature selec ...