poj 2778:DNA Sequence
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
求长度为n仅由ATGC构成的字符串中不包含给定串的数量
这种记路径的方法算是个考点了吧(好像套DP只能这么出?
#include<queue> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; inline int f(char u){ if (u=='A') return 0;else if (u=='C') return 1;else if (u=='G') return 2;else if (u=='T') return 3; } struct tree{ int f; bool w; int t[4]; }t[10001]; const long long MOD=100000; int tt,n,m,num=0; struct MX{ long long c[105][105]; }; char s[1000]; bool ma[105],us[105]; queue <int> q; inline void M(int &x){ if (x>=MOD) x-=MOD; } inline bool dfs(int x){ if (x==0) return 1; if (t[x].w) return 0; if (us[x]) return ma[x]; us[x]=1; return ma[x]=dfs(t[x].f); } inline void in(){ int p=0,l,m=strlen(s); for (register int i=0;i<m;i++){ l=f(s[i]); if (!t[p].t[l]) t[p].t[l]=++num; p=t[p].t[l]; } t[p].w=1; } inline void mafa(){ register int i;int k,p; q.push(0);t[0].f=0; while(!q.empty()){ k=q.front();q.pop(); for (i=0;i<4;i++) if (t[k].t[i]){ p=t[k].f; while((!t[p].t[i])&&p) p=t[p].f; t[t[k].t[i]].f=(k==p)?0:t[p].t[i]; q.push(t[k].t[i]); } } } inline MX cheng(MX x,MX y){ register int i,j,k; MX z; for (i=0;i<=num;i++) if (ma[i]) for (j=0;j<=num;j++) if (ma[j]) z.c[i][j]=0; for (i=0;i<=num;i++) if (ma[i]) for (j=0;j<=num;j++) if (ma[j]) for (k=0;k<=num;k++) if (ma[k]) z.c[i][j]+=x.c[i][k]*y.c[k][j],z.c[i][j]%=MOD; return z; } inline MX mi(MX x,int a){ register int i,j; MX z=x;a--; while(a){ if (a&1) z=cheng(z,x); a>>=1; x=cheng(x,x); } return z; } int main(){ register int i,j;int u; scanf("%d%d",&n,&m); num=0; for (i=1;i<=n;i++){ scanf("%s",s); in(); } mafa(); MX a; for (i=0;i<=num;i++) ma[i]=dfs(i); for (i=0;i<=num;i++) if (ma[i]) for (j=0;j<4;j++){ if (!t[i].t[j]){ u=t[i].f; while(!t[u].t[j]&&u)u=t[u].f; u=t[u].t[j]; }else u=t[i].t[j]; a.c[i][u]++; } a=mi(a,m); u=0; for (i=0;i<=num;i++) if (ma[i]) u+=a.c[0][i],M(u); printf("%d\n",u); }