DNA Sequence
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 10757 | Accepted: 4104 |
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.
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.
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自动机+矩阵快速幂。
sb错误纠结一晚上,吐槽一下。
/* ***********************************************
Author :xianxingwuguan
Created Time :2014-2-2 22:56:06
File Name :1.cpp
************************************************ */
#pragma comment(linker, "/STACK:102400000,102400000")
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <string>
#include <time.h>
#include <math.h>
#include <queue>
#include <stack>
#include <set>
#include <map>
using namespace std;
#define INF 0x3f3f3f3f
#define eps 1e-8
#define pi acos(-1.0)
typedef long long ll;
const ll mod=100000;
struct Matrix{
ll n,mat[200][200];
Matrix(){}
Matrix(ll _n){
n=_n;
for(ll i=0;i<n;i++)
for(ll j=0;j<n;j++)
mat[i][j]=0;
}
};
Matrix mul(Matrix a,Matrix b){
Matrix ans=Matrix(a.n);
for(ll i=0;i<a.n;i++)
for(ll j=0;j<a.n;j++)
for(ll k=0;k<a.n;k++)
ans.mat[i][j]=(ans.mat[i][j]+a.mat[i][k]*b.mat[k][j])%mod;
return ans;
}
Matrix pw(Matrix a,ll n){
Matrix ans=Matrix(a.n);
for(ll i=0;i<a.n;i++)
ans.mat[i][i]=1;
while(n){
if(n%2)
ans=mul(ans,a);
a=mul(a,a);
n>>=1;
}
return ans;
}
struct Trie{
ll next[300][4],fail[300],end[300];
ll L,root;
ll newnode(){
for(ll i=0;i<4;i++)
next[L][i]=-1;
end[L++]=0;
return L-1;
}
void init(){
L=0;
root=newnode();
}
ll id(char ch){
if(ch=='A')return 0;
if(ch=='T')return 1;
if(ch=='C')return 2;
return 3;
}
void insert(char *str){
ll len=strlen(str);
ll now=root;
for(ll i=0;i<len;i++){
ll p=id(str[i]);
if(next[now][p]==-1)
next[now][p]=newnode();
now=next[now][p];
}
end[now]=1;
}
void build(){
queue<ll> q;
fail[root]=root;
for(ll i=0;i<4;i++)
if(next[root][i]==-1)
next[root][i]=root;
else {
fail[next[root][i]]=root;
q.push(next[root][i]);
}
while(!q.empty()){
ll now=q.front();
q.pop();
if(end[fail[now]])end[now]=1;
for(ll i=0;i<4;i++)
if(next[now][i]==-1)
next[now][i]=next[fail[now]][i];
else {
fail[next[now][i]]=next[fail[now]][i];
q.push(next[now][i]);
}
}
}
Matrix solve(){
Matrix ans=Matrix(L);
for(ll i=0;i<L;i++)
if(!end[i])
for(ll j=0;j<4;j++)
if(!end[next[i][j]])
ans.mat[i][next[i][j]]++;
return ans;
}
}ac;
char str[1000];
void debug(Matrix a){
cout<<"111: "<<a.n<<endl;
for(ll i=0;i<a.n;i++){
for(ll j=0;j<a.n;j++)
cout<<a.mat[i][j]<<" ";
cout<<endl;
}
}
int main()
{
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
ll i,j,k,m,n;
while(cin>>n>>m){
ac.init();
while(n--){
scanf("%s",str);
ac.insert(str);
}
// cout<<"hahha:"<<endl;
ac.build();
Matrix ans=ac.solve();
// debug(ans);
ans=pw(ans,m);
ll ret=0;
for(i=0;i<ac.L;i++)
ret=(ret+ans.mat[0][i])%mod;
cout<<ret<<endl;
}
return 0;
}