http://www.elijahqi.win/archives/2886
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
和上午做的一题完全相同 只不过这次改成了求不会出现的个数 而且这个n这么大 然后字符串的长度这么小可以想象到用矩阵快速幂优化下dp转移即可ac 另外意识到取模真的很慢..
#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define mod 100000
#define N 110
#define ll long long
using namespace std;
int cnt=1,n,m,trans[N][4],c[500],fail[N];char s[11];bool end[N];
inline void insert1(char s[]){
int len=strlen(s+1);int p=1;
for (int i=1,nxt;i<=len;++i){
if (!trans[p][c[s[i]]]) trans[p][c[s[i]]]=nxt=++cnt;
else nxt=trans[p][c[s[i]]];p=nxt;
}end[p]=1;
}
inline void buildAC(){
queue<int> q;q.push(1);for (int i=0;i<4;++i) trans[0][i]=1;
while(!q.empty()){
int x=q.front();q.pop();
for (int i=0;i<4;++i){
int &y=trans[x][i];
if (y) fail[y]=trans[fail[x]][i],q.push(y);
else {y=trans[fail[x]][i];continue;}end[y]|=end[fail[y]];
}
}
}
struct matrix{ll f[110][110];}ans,base;
inline matrix multiply(const matrix &a,const matrix &b){
matrix c;memset(c.f,0,sizeof(c.f));
for (int i=1;i<=cnt;++i)
for (int k=1;k<=cnt;++k)
for (int j=1;j<=cnt;++j)
c.f[i][j]+=a.f[i][k]*b.f[k][j];
for (int i=1;i<=cnt;++i)
for (int j=1;j<=cnt;++j) c.f[i][j]%=mod;
return c;
}
int main(){
freopen("poj2778.in","r",stdin);
scanf("%d%d",&m,&n);c['A']=0;c['T']=1;c['C']=2;c['G']=3;
for (int i=1;i<=m;++i) scanf("%s",s+1),insert1(s);buildAC();
for (int i=1;i<=cnt;++i){
if (end[i])continue;
for (int j=0;j<4;++j){
if(end[trans[i][j]]) continue;
++base.f[i][trans[i][j]];
}
}for (int i=1;i<=cnt;++i) ans.f[i][i]=1;int ans1=0;
for (int t=n;t;t>>=1,base=multiply(base,base)) if (t&1) ans=multiply(ans,base);
for (int i=1;i<=cnt;++i) ans1=ans1+ans.f[1][i]>=mod?ans1+ans.f[1][i]-mod:ans1+ans.f[1][i];
printf("%d\n",ans1);
return 0;
}