0
点赞
收藏
分享

微信扫一扫

POJ 2778 DNA Sequence (AC自动机+矩阵加速,4级)


E - DNA Sequence


Crawling in process...

Crawling failed

Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u


​​Submit​​​ ​​​Status​​


System Crawler (2013-05-30)



Description



It's well known that DNA Sequence is a sequence only contains A, C, T and G, and it's very useful to analyze a segment of DNA Sequence,For example, if a animal's DNA sequence contains segment ATC then it may mean that the animal may have a genetic disease. Until now scientists have found several those segments, the problem is how many kinds of DNA sequences of a species don't contain those segments.

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



First line contains two integer m (0 <= m <= 10), n (1 <= n <=2000000000). Here, m is the number of genetic disease segment, and n is the length of sequences.

Next m lines each line contain a DNA genetic disease segment, and length of these segments is not larger than 10.



Output



An integer, the number of DNA sequences, mod 100000.



Sample Input



4 3 AT AC AG AA



Sample Output



36




思路:直接用AC自动机预处理出失败指针转移态,然后根据失败指针的转移态建立递推矩阵,外加个快速幂轻松搞定。



mod很占时间能不mod尽量少mod




#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#define FOR(i,a,b) for(int i=a;i<=b;++i)
#define clr(f,z) memset(f,z,sizeof(f))
#define LL unsigned long long
using namespace std;
const int msize=510;
const int sig=4;
const int mod=100000;
class Matrix
{
public:
LL f[140][140];
int n;
Matrix();
Matrix(int x)
{
n=x;
FOR(i,0,x-1)FOR(j,0,x-1)f[i][j]=0;
}
Matrix operator*(const Matrix&b)const
{
Matrix c=Matrix(n);
FOR(i,0,n-1)FOR(j,0,n-1){FOR(k,0,n-1)
c.f[i][j]+=f[i][k]*b.f[k][j];
c.f[i][j]%=mod;
}
return c;
}
};
class AC_Machine
{
public:int f[msize],ch[msize][sig],sz;
bool val[msize];
void clear()
{
sz=1;clr(ch[0],0);val[0]=0;
}
int idx(char x)
{
if(x=='A')return 0;
if(x=='G')return 1;
if(x=='C')return 2;
if(x=='T')return 3;
}
void insert(char*s)
{
int u=0,v,c;
for(int i=0;s[i];++i)
{
c=idx(s[i]);
if(!ch[u][c])
{
clr(ch[sz],0);val[sz]=0;
ch[u][c]=sz++;
}
u=ch[u][c];
}
val[u]=1;
}
void getFail()
{
int u=0,v,r;
queue<int>Q;
FOR(c,0,sig-1)
{
u=ch[0][c];
if(u)
{
f[u]=0;Q.push(u);
}
}
while(!Q.empty())
{
r=Q.front();Q.pop();
val[r]|=val[ f[r] ];
FOR(c,0,sig-1)
{
u=ch[r][c];
if(!u)
{
ch[r][c]=ch[ f[r] ][c];continue;
}
v=f[r];Q.push(u);
while(v&&!ch[v][c])v=f[v];
f[u]=ch[v][c];
}
}
}
Matrix getMatrix()
{
Matrix ret=Matrix(sz);
FOR(i,0,sz-1)
FOR(j,0,3)
if(!val[ch[i][j]])
{
ret.f[i][ ch[i][j] ]++;
}
return ret;
}
};
Matrix M_pow(Matrix a,int m)
{
Matrix ret=Matrix(a.n);
FOR(i,0,a.n-1)ret.f[i][i]=1;
while(m)
{
if(m&1)ret=ret*a;
a=a*a;
m>>=1;
}
return ret;
}
AC_Machine ac;
char s[55];
int n,m;
int main()
{
while(~scanf("%d%d",&n,&m))
{
ac.clear();
FOR(i,1,n)
{
scanf("%s",s);
ac.insert(s);
}
ac.getFail();
Matrix ret=ac.getMatrix();
ret=M_pow(ret,m);
LL ans=0;
FOR(i,0,ac.sz-1)
ans+=ret.f[0][i];
ans%=mod;
printf("%lld\n",ans);
}
}



举报

相关推荐

0 条评论