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. 

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仅由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
",u);
}
View Code
 
原文地址:https://www.cnblogs.com/Enceladus/p/5308718.html