DNA Sequence
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 15900 Accepted: 6137
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
Source
POJ Monthly–2006.03.26,dodo
题意:给你一些串,让你求有多少个长度为m的串不包含这些串。
一开始我想的容斥。。把不合法方案剪掉,但是发现不合法方案数非常难计算,因为子串出现的位置不固定,根本没地方下手。。然后就dp喽,但是这么大,用矩阵乘法优化了一下,结果半天RE,不知道哪里错了,看了看题解和我一样啊,一看代码发现怎么人家的getfail好像不太一样?一脸懵逼。结果发现都差不多啊,怎么会有问题呢。。
最后发现我手抖把加进队列的达成了fail节点。。mdzz。。
顺便熟悉一下结构体,毕竟以后肯定很有用。。
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<iostream>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
const int N=1005;
typedef long long ll;
const int mo=1e5;
int a[N][10],val[N],fail[N],q[N],ans;
int tot=0,n;
char s[N];
ll m;
struct Matrix
{
ll ret[105][105];
Matrix(){memset(ret,0,sizeof(ret));}
void ini()
{
fo(i,0,tot)ret[i][i]=1;
}
}g;
Matrix operator *(Matrix a,Matrix b)
{
Matrix c;
fo(k,0,tot)
fo(i,0,tot)if (a.ret[i][k])
fo(j,0,tot)if (b.ret[k][j])
c.ret[i][j]=(c.ret[i][j]+a.ret[i][k]*b.ret[k][j]%mo)%mo;
return c;
}
Matrix operator ^(Matrix a,int b)
{
Matrix ans;ans.ini();
for(;b;b>>=1,a=a*a)
if (b&1)ans=ans*a;
return ans;
}
inline void ins()
{
int x=0,len=strlen(s);
fo(i,0,len-1)
{
int c;
if (s[i]=='A')c=1;
else if (s[i]=='T')c=2;
else if (s[i]=='C')c=3;
else if (s[i]=='G')c=4;
c--;
if(!a[x][c])a[x][c]=++tot;
x=a[x][c];
}
val[x]=1;
}
inline void getfail()
{
int t=0,w=0;
fo(i,0,3)if (a[0][i])q[w++]=a[0][i];
while(t<w)
{
int x=q[t++];
fo(i,0,3)
if (a[x][i])
{
int k=fail[x];
while (k&&!a[k][i])k=fail[k];
k=a[k][i];
fail[a[x][i]]=k;
if (val[k])val[a[x][i]]=1;
q[w++]=a[x][i];
}
else a[x][i]=a[fail[x]][i];
}
}
inline void build()
{
fo(i,0,tot)if (!val[i])
fo(k,0,3)if (!val[a[i][k]])
g.ret[i][a[i][k]]++;
}
int main()
{
scanf("%d%lld",&n,&m);
fo(i,1,n)
{
scanf("%s",s);
ins();
}
getfail();
build();
g=g^m;
ll ans=0;
fo(i,0,tot)ans=(ans+g.ret[0][i])%mo;
printf("%lld",ans);
}