您的位置:首页 > 产品设计 > UI/UE

[AC自动机+dp+矩阵快速幂] poj 2778 DNA Sequence

2014-05-20 20:28 183 查看
http://www.cppblog.com/menjitianya/archive/2014/07/11/207604.html#207622

解释的很清楚了 贴个代码!

代码:

#include"cstdlib"
#include"cstdio"
#include"cstring"
#include"cmath"
#include"queue"
#include"algorithm"
#include"iostream"
using namespace std;
int triecont;
struct trie
{
    int mark,id;
    trie *next[5];
    trie *fail;
    trie()
    {
        mark=id=0;
        memset(next,0,sizeof(next));
        fail=NULL;
    }
};
struct matrix
{
    __int64 mat[100][100];
};
trie *root;
int getid(char x)
{
    if(x=='A') return 0;
    else if(x=='C') return 1;
    else if(x=='G') return 2;
    return 3;
}
void init(char *v)
{
    trie *p=root;
    for(int i=0; v[i]; i++)
    {
        int tep=getid(v[i]);
        if(p->next[tep]==NULL)
        {
            p->next[tep]=new trie();
            p->next[tep]->id=triecont++;
        }
        p=p->next[tep];
    }
    p->mark++;
}
void getac()
{
    queue<trie*>q;
    q.push(root);
    while(!q.empty())
    {
        trie *p;
        p=q.front();
        q.pop();
        for(int i=0; i<4; i++)
        {
            if(p->next[i]==NULL)
            {
                if(p==root) p->next[i]=root;
                else p->next[i]=p->fail->next[i];
            }
            else
            {
                if(p==root) p->next[i]->fail=root;
                else  p->next[i]->fail=p->fail->next[i];
                q.push(p->next[i]);
            }
        }
    }
}
matrix matmul(matrix a,matrix b,int n,int m)
{
    int i,j,k;
    matrix c;
    memset(c.mat,0,sizeof(c.mat));
    for(i=0; i<n; i++)
    {
        for(j=0; j<n; j++)
        {
            for(k=0; k<n; k++)
            {
                c.mat[i][j]+=a.mat[i][k]*b.mat[k][j];
            }
            c.mat[i][j]%=m;
        }
    }
    return c;
}
matrix matpow(matrix a,int k,int n,int m)
{
    matrix b;
    int i;
    memset(b.mat,0,sizeof(b.mat));
    for(i=0; i<n; i++) b.mat[i][i]=1;
    while(k)
    {
        if(k&1) b=matmul(a,b,n,m);
        a=matmul(a,a,n,m);
        k>>=1;
    }
    return b;
}
int main()
{
    int m,n;
    while(scanf("%d%d",&m,&n)!=-1)
    {
        triecont=0;
        root=new trie();
        root->id=triecont++;
        while(m--)
        {
            char x[12];
            scanf("%s",x);
            init(x);
        }
        getac();
        matrix b,ans;
        int used[123],hash[123];
        memset(b.mat,0,sizeof(b.mat));
        memset(used,0,sizeof(used));
        memset(hash,0,sizeof(hash));
        queue<trie*>q;
        q.push(root);
        while(!q.empty())
        {
            trie *p,*tep;
            tep=p=q.front();
            q.pop();
            if(hash[p->id]) continue;
            else hash[p->id]=1;
            while(tep!=NULL && tep->mark==0 ) tep=tep->fail;
            if(tep==NULL)
            {
                for(int i=0; i<4; i++)
                {
                    if(hash[p->next[i]->id]==0) q.push(p->next[i]);
                    b.mat[p->id][p->next[i]->id]++;
                }
            }
            else
            {
                b.mat[p->id][p->id]=4;
                used[p->id]=1;
            }
        }
        ans=matpow(b,n,triecont,100000);
        __int64 sum=0;
        for(int i=0; i<triecont; i++) if(used[i]==0) sum+=ans.mat[0][i];
        printf("%I64d\n",sum%100000);
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: