• POJ 3691 DNA Sequence (AC自动机 + 矩阵 有bug,待修改)


    DNA Sequence
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 9889   Accepted: 3712

    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

     
     
     
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    
    using namespace std;
    
    const int N=110;
    const int mod=100000;
    
    struct Trie{
        int ok;
        int fail;
        int next[4];
        void Init(){
            ok=0;
            fail=-1;
            memset(next,-1,sizeof(next));
        }
    }a[N];
    
    char wrd[30];
    char str[N];
    int n,m,cnt,q[N];
    
    int find(char ch){
        switch(ch){
            case 'A':return 0;
            case 'C':return 1;
            case 'T':return 2;
            case 'G':return 3;
        }
        return 0;
    }
    
    void InsertTrie(char *str){
        int p=0;
        for(int i=0;str[i]!='';i++){
            int id=find(str[i]);
            if(a[p].ok)
                break;
            if(a[p].next[id]==-1){
                a[p].next[id]=cnt++;
                a[cnt-1].Init();
            }
            p=a[p].next[id];
        }
        a[p].ok++;
    }
    
    void AC_automation(){
        int head=0,tail=0;
        q[tail++]=0;
        int cur=0,tmp;
        while(head<tail){
            cur=q[head++];
            for(int i=0;i<4;i++){
                tmp=a[cur].next[i];
                if(tmp!=-1){
                    if(cur==0)
                        a[tmp].fail=0;
                    else{
                        a[tmp].fail=a[a[cur].fail].next[i];
                        if(a[a[tmp].fail].ok)
                            a[tmp].ok++;
                    }
                    q[tail++]=a[cur].next[i];
                }else{
                    if(cur==0)
                        a[cur].next[i]=0;
                    else
                        a[cur].next[i]=a[a[cur].fail].next[i];
                }
            }
        }
    }
    
    struct Matrix{
        long long m[110][110];
    };
    
    Matrix init,unit;
    
    void Init(){
        memset(init.m,0,sizeof(init.m));
        for(int i=0;i<cnt;i++)
            if(!a[i].ok)
                for(int j=0;j<4;j++){
                    if(a[a[i].next[j]].ok==0)
                        init.m[i][a[i].next[j]]++;
                }
                    //if(a[*a[i].next[j]].ok==0)
                        //init.m[i][*a[i].next[j]]++;
        for(int i=0;i<cnt;i++)
            for(int j=0;j<cnt;j++)
                unit.m[i][j]=(i==j)?1:0;
    }
    
    Matrix Mul(Matrix a,Matrix b){
        Matrix c;
        for(int i=0;i<cnt;i++)
            for(int j=0;j<cnt;j++){
                c.m[i][j]=0;
                for(int k=0;k<cnt;k++)
                    c.m[i][j]=(a.m[i][k]*b.m[k][j])%mod;
                c.m[i][j]%=mod;
            }
        return c;
    }
    
    Matrix Pow(Matrix a,Matrix b,int k){
        while(k){
            if(k&1){
                b=Mul(a,b);
            }
            a=Mul(a,a);
            k>>=1;
        }
        return b;
    }
    
    int main(){
    
        freopen("input.txt","r",stdin);
    
        while(~scanf("%d%d",&n,&m)){
            cnt=1;
            a[0].Init();
            for(int i=0;i<n;i++){
                scanf("%s",wrd);
                InsertTrie(wrd);
            }
            AC_automation();
            Init();
            Matrix res=Pow(init,unit,m);
            long long ans=0;
            for(int i=0;i<cnt;i++)
                if(a[i].ok==0)
                    ans=(ans+res.m[0][i])%mod;
            cout<<ans<<endl;
        }
        return 0;
    }
  • 相关阅读:
    【Vegas原创】mysql更改用户密码之无敌方法
    【Vegas原创】Xcopy屡试不爽
    【Vegas原创】ctrl shift无法切换输入法的解决方法
    【Vegas原创】将SQLServer表、视图、存储过程的所有者批量改为dbo的处理方法
    【Vegas原创】SQL Server2005应急备机切换步骤 生产机正常
    【Vegas原创】SQLServer 2000 企业管理器展开数据库列表错误的解决方法
    【Vegas原创】win7下打开telnet服务
    【Vegas原创】Windows 2003下CACTI的安装及配置
    【Vegas原创】SecureCRT个性化设置
    Mathematica实现微分算子功能
  • 原文地址:https://www.cnblogs.com/jackge/p/3147573.html
Copyright © 2020-2023  润新知