poj2778 DNA Sequence(AC自动机+矩阵快速幂)

题目链接:点击打开链接

题意描述:给m字符串,这m个字符串是带有病毒的DNA。然后问一个长度为n的字符串不带有任何病毒有多少中可能?所有字符串之后ACGT这几个字符串组成


解题思路:AC自动机+矩阵快速幂

前置内容:邻接矩阵幂的含义:点击打开链接

分析:首先根据题意先建一个AC自动机,其实AC自动机本身就是一张图,AC自动机中的每个结点就相当于图中的顶点,每个转移A、C、G、T就相当于一条边;根据邻接矩阵幂的含义,我们发现求长度为n的字符串的个数就相当于从起点在图中走n步所能到达的所点的方案数的和,而n又很大,我们可以使用矩阵快速幂;但是本题有限制就是不能带有某些字符串,言外之意就是图中有些节点不能经过,根据AC自动机中的end[i]我们可以将这种情况去掉


代码:

#include 
#include 
#include 
#define MOD 100000
typedef long long ll;
using namespace std;
struct Matrix{
    ll m[110][110];
    int L;
    Matrix(int len){
        L=len;
        for(int i=0;i>1;
        a=mat(a,a);
    }
    return t;
}
struct Trie{
    int next1[110][4],fail[110];
    bool end1[110];
    int root,L;
    int newnode(){
        for(int i=0;i<4;++i) next1[L][i]=-1;
        end1[L++]=false;
        return L-1;
    }
    void init(){ L=0; root=newnode(); }
    int getchs(char ch){
        switch(ch){
        case 'A': return 0;break;
        case 'C': return 1;break;
        case 'G': return 2;break;
        case 'T': return 3;break;
        }
    }
    void insertnode(char* str){
        int now=root;
        int len=strlen(str);
        for(int i=0;i q;
        for(int i=0;i<4;++i){
            if(next1[root][i]==-1) next1[root][i]=root;
            else{
                fail[next1[root][i]]=root;
                q.push(next1[root][i]);
            }
        }
        while(!q.empty()){
            int now=q.front(); q.pop();
            if(end1[fail[now]]==true)///注意
                end1[now]=true;
            for(int i=0;i<4;++i){
                if(next1[now][i]==-1) next1[now][i]=next1[fail[now]][i];
                else {
                    fail[next1[now][i]]=next1[fail[now]][i];
                    q.push(next1[now][i]);
                }
            }
        }
    }
    Matrix getMatrix(){
        Matrix res = Matrix(L);
        for(int i=0;i




你可能感兴趣的:(字符串)