DNA Sequence
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 14224 Accepted: 5486
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
题意:给你n个病毒,求m长度的正常DNA序列的个数;
思路:在trie树上的递推,二维数组表示路径的方案数,快速幂解;
从0的dp[0][i]的和;
#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<queue>
#include<string.h>
using namespace std;
long long b[110][110];
int n,m;
char s[115];
int MOD=100000;
int ans=0;
int flag[110];
int tot;
int nex[110];
long long cc[110][110];
long long ccc[110][110];
struct node{
int ch[4];
}t[110];
int val(char s)
{
if(s=='A') return 0;
if(s=='C') return 1;
if(s=='T') return 2;
if(s=='G') return 3;
}
inline void insert(char s[])
{
// cout<<" "<<s[0]<<endl;
// cout<<tot<<endl;
int now=0;
for(int i=0;s[i];i++)
{
int ii=val(s[i]);
//cout<<i<<endl;
if(!t[now].ch[ii])
{
t[now].ch[ii]=++tot;
}
now=t[now].ch[ii];
}
flag[now]=1;
}
queue<int> q;
inline void AC()
{
for(int i=0;i<4;i++) if(t[0].ch[i]) q.push(t[0].ch[i]);
while(!q.empty())
{
int now=q.front();
q.pop();
int next=nex[now];
for(int i=0;i<4;i++)
{
// if(now==3) cout<<t[3].ch[2]<<endl;
// if(now==4) cout<<" "<<t[now].ch[i]<<endl;
if(t[now].ch[i])
{
nex[t[now].ch[i]]=t[next].ch[i];
flag[t[now].ch[i]]|=flag[t[next].ch[i]];
q.push(t[now].ch[i]);
}
else t[now].ch[i]=t[next].ch[i];
}
}
}
inline void ma_cheng(long long a[110][110],long long tmp[110][110])
{
for(int i=0;i<=tot;i++)
for(int j=0;j<=tot;j++)
{
cc[i][j]=0;
for(int k=0;k<=tot;k++)
{
cc[i][j]+=a[i][k]*tmp[k][j];
cc[i][j]%=MOD;
}
}
// for(int i=0;i<=5;i++)
//{
//for(int j=0;j<=5;j++)
//cout<<cc[i][j]<<" ";
//cout<<endl;
//}
//cout<<endl;
for(int i=0;i<=tot;i++)
for(int j=0;j<=tot;j++)
{
tmp[i][j]=cc[i][j];
}
}
inline void ma_mi(int x)
{
for(int i=0;i<=tot;i++)
for(int j=0;j<=tot;j++)
ccc[i][j]=b[i][j];
while(x>0)
{
// cout<<" "<<x<<endl;
if(x&1) ma_cheng(ccc,b);
ma_cheng(ccc,ccc);
x>>=1;
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%s",s);
insert(s);
}
AC();
//cout<<tot<<endl;
for(int i=0;i<=tot;i++)
if(!flag[i])
{
for(int j=0;j<4;j++)
if(!flag[t[i].ch[j]])
{
b[i][t[i].ch[j]]++;
}
}
// cout<<tot<<endl;
//for(int i=0;i<=7;i++)
//{
//for(int j=0;j<=7;j++)
//cout<<b[i][j]<<" ";
//cout<<endl;
//}
ma_mi(m-1);
ans=0;
for(int i=0;i<=tot;i++)
if(!flag[i])
{
ans+=b[0][i];
ans%=MOD;
}
cout<<ans<<endl;
}