zoukankan      html  css  js  c++  java
  • POJ-2778

    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 12726   Accepted: 4862

    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

    推荐一个网址 :Maxtrix67

    /**
        题意:给出n个字符串,问长度为m的字符串中有多少没有包含病毒
        做法:AC自动机 + 矩阵快速幂 
            Maxtrix 67 给出的定理8
            经典题目8 给定一个有向图,问从A点恰好走k步(允许重复经过边)到达B点的方案数mod p的值
            把给定的图转为邻接矩阵,即A(i,j)=1当且仅当存在一条边i->j。  令C=A*A,
            那么C(i,j)=ΣA(i,k)*A(k,j),实际上就等于从点i到点j恰好经过2条边的路径数(枚举k为中转点)。
            类似地,C*A的第i行第j列就表示从i到j经过3条边的路径数。同理,如果要求经过k步的路径数,
            我们只需要二分求出A^k即可。
    **/
    #include <iostream>
    #include <cmath>
    #include <stdio.h>
    #include <algorithm>
    #include <string.h>
    #include <queue>
    #include <map>
    #define MM 10
    #define mod 100000
    using namespace std;
    struct Matrix
    {
        unsigned long long mat[140][140];
        int n;
        Matrix(){}
        Matrix(int _n)
        {
            n = _n;
            for(int i=0;i<n;i++)
            {
                for(int j=0;j<n;j++)
                {
                    mat[i][j] = 0;
                }
            }
        }
        Matrix operator *(const Matrix &b) const
        {
            Matrix res = Matrix(n);
            for(int i=0;i<n;i++)
            {
                for(int j=0;j<n;j++)
                {
                    res.mat[i][j] = 0;
                    for(int k=0;k<n;k++)
                    {
                        res.mat[i][j] += mat[i][k] * b.mat[k][j];
                    }
                    res.mat[i][j] %= mod;
                }
            }
            return res;
        }
    };
    unsigned long long quick_pow(unsigned long long a,int n)
    {
        unsigned long long res = 1;
        unsigned long long tmp = a;
        while(n)
        {
            if(n&1) res *= tmp;
            tmp *= tmp;
            n >>= 1;
        }
        return res;
    }
    Matrix quick_pow(Matrix a,int n)
    {
        Matrix res = Matrix(a.n);
        for(int i=0;i<a.n;i++)
        {
            res.mat[i][i] = 1;
        }
        Matrix tmp = a;
        while(n)
        {
            if(n&1) res =res * tmp;
            tmp = tmp * tmp;
            n >>= 1;
        }
        return res;
    }
    struct Tire
    {
        int next[110][MM],fail[110];
        bool end[110];
        int L,root;
        map<char,int>id;
        int newnode()
        {
            for(int i=0;i<MM;i++)
            {
                next[L][i] = -1;
            }
            end[L++] = 0;
            return L-1;
        }
        void init()
        {
            L = 0;
            root = newnode();
            id['A'] = 0;
            id['T'] = 1;
            id['C'] = 2;
            id['G'] = 3;
        }
        void insert(char buf[])
        {
            int now = root;
    
            int len = strlen(buf);
            for(int i=0;i<len;i++)
            {
                if(next[now][id[buf[i]]] == -1)
                    next[now][id[buf[i]]] = newnode();
                now = next[now][id[buf[i]]];
            }
            end[now] = true;
        }
        void build()
        {
            queue<int>que;
            int now = root;
            fail[root] = root;
            for(int i=0;i<4;i++)
            {
                if(next[now][i] == -1)
                    next[now][i] = root;
                else
                {
                    fail[next[now][i]] = root;
                    que.push(next[now][i]);
                }
            }
            while(!que.empty())
            {
                now = que.front();
                que.pop();
                if(end[fail[now]]) end[now] = true;
                for(int 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];
                        que.push(next[now][i]);
                    }
                }
            }
        }
        Matrix getMatrix()
        {
            Matrix res = Matrix(L+1);
            for(int i=0;i<L;i++)
            {
                for(int j=0;j<4;j++)
                {
                    if(end[next[i][j]] == false && !end[i])
                        res.mat[i][next[i][j]] ++;
                }
            }
            return res;
        }
    };
    char buf[100];
    Tire ac;
    int main()
    {
       // freopen("in.txt","r",stdin);
        int n,m;
        while(~scanf("%d %d",&n,&m))
        {
            ac.init();
            for(int i=0;i<n;i++)
            {
                scanf("%s",buf);
                ac.insert(buf);
            }
            ac.build();
            Matrix a = ac.getMatrix();
            a = quick_pow(a,m);
            unsigned long long res = 0;
            for(int i=0;i<a.n;i++)
            {
                res += a.mat[0][i];
            }
            cout<<res%mod<<endl;
        }
        return 0;
    }
  • 相关阅读:
    Linux 内核剖解(转)
    计算机系统的分层结构
    Linux学习之路三:重要概念之Linux系统层次结构
    库函数与系统调用的联系与区别
    库函数与系统调用
    库函数调用和系统调用的区别
    标准库函数和系统调用的区别
    关于Linux操作系统层次结构分析
    linux标准输入输出
    C语言的标准输入输出
  • 原文地址:https://www.cnblogs.com/chenyang920/p/4487352.html
Copyright © 2011-2022 走看看