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

http://www.cppblog.com/menjitianya/archive/2014/07/10/207604.html

上面的网站介绍了字典树、失配指针、Trie图,讲的很清晰

题意:给你n个串,求一个长度为m的不包含给定串的串的个数
需要的知识点:知道AC自动机和Trie图、矩阵快速幂、m[i][j] = x表示i到j结点有长度为1的路有x条,那么m的n次幂c[][]就表示i到j结点长度为n的路有c[i][j]

思路分析:最重要的一步就是求Trie图,通过Trie图确定结点之间的路径条数,然后它的m次幂就表示长度为m的路径条数,答案就是从0结点出发到任意结点的长度为n的路径个数之和

这里在提醒下:poj上G++的运行速度比C++快

代码如下:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#define N 105
#define MOD 100000
#define inf 0x7ffffff
#define eps 1e-9
#define pi acos(-1.0)
using namespace std;
int f[N];
int getnum(char c)
{
    switch(c)
    {
        case 'A':return 0;
        case 'T':return 1;
        case 'C':return 2;
        case 'G':return 3;
    }
}
struct Matrix
{
    int m[N][N];
    Matrix(){
        memset(m,0,sizeof(m));
    }
}I;
void get_I()
{
    int i,j;
    memset(I.m,0,sizeof(I.m));
    for(i = 0; i < N; i++)
        for(j = 0; j < N; j++)
            if(i == j)  I.m[i][j] = 1;
}
struct node
{
    int ch[N][5];
    int val[N];
    int sz;
    void init()
    {
        sz = 1;
        memset(ch,0,sizeof(ch));
        memset(val,0,sizeof(val));
        memset(f,0,sizeof(f));
    }
    void insert(char *str)
    {
        int len = strlen(str);
        int i, u = 0;
        for(i = 0; i < len; i++)
        {
            int c = getnum(str[i]);
            if(ch[u][c] == 0)
                ch[u][c] = sz++;
            u = ch[u][c];
        }
        val[u] = 1;
    }
    void GetFail()//构建fail指针,利用fail指针建立Trie图
    {
        queue<int> q;
        f[0] = 0;
        int i;
        for(i = 0; i < 4; i++)
        {
            int u = ch[0][i];
            if(u == 0)
                ch[0][i] = 0;
            else{
                q.push(u);
                f[u] = 0;
            }
        }
        while(!q.empty())
        {
            int u = q.front();
            q.pop();
            if(val[f[u]])
                val[u] = 1;
            for(i = 0; i < 4; i++)
            {
                int v = ch[u][i];
                if(v == 0)
                    ch[u][i] = ch[f[u]][i];
                else{
                    q.push(v);
                    f[v] = ch[f[u]][i];
                }
            }
        }
    }

    Matrix get_matrix()
    {
        int i,j;
        Matrix a;
        for(i = 0; i < sz; i++)
            for(j = 0; j < 4; j++)
            {
                int u = ch[i][j];
                if(val[u] == 0)
                    a.m[i][u]++;
            }
        return a;
    }
}Trie;
Matrix matrixmul(Matrix a,Matrix b,int n)
{
    int i,j,k;
    Matrix c;
    for(i = 0; i < n; i++)
        for(j = 0; j < n; j++)
            for(k = 0; k < n; k++)
                c.m[i][j] = (c.m[i][j] + ((long long)a.m[i][k]*b.m[k][j])%MOD)%MOD;
    return c;
}
Matrix matrixpow(Matrix a,int n,int k)
{
     Matrix c = a;
     Matrix b = I;
     while(n)
     {
         if(n&1)
            b = matrixmul(b,c,k);
         n >>= 1;
         c = matrixmul(c,c,k);
     }
     return b;
}
int main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
    int n,m;
    get_I();
    while(scanf("%d%d",&n,&m) != EOF)
    {
         Trie.init();
         char str[20];
         int i;
         for(i = 0; i < n; i++)
         {
             scanf("%s",str);
             printf("%s\n",str);
             Trie.insert(str);
         }
         Trie.GetFail();
         Matrix a;
         a = Trie.get_matrix();
         a = matrixpow(a,m,Trie.sz);
         int ans = 0;
         for(i = 0; i < Trie.sz; i++)
            ans = (ans + a.m[0][i])%MOD;
         printf("%d\n",ans);
    }
    return 0;
}


1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。、可私 6信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。、可 6私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。、可私 6信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值