poj2778(AC自动机+矩阵快速幂)
来源:互联网 发布:mac论坛 编辑:程序博客网 时间:2024/05/18 00:06
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;}
0 0
- poj2778(AC自动机+矩阵快速幂)
- poj2778之AC自动机+矩阵快速幂
- poj2778 AC自动机+矩阵快速幂
- poj2778 DNA Sequence(AC自动机+矩阵快速幂 )
- poj2778 DNA Sequence(AC自动机+矩阵快速幂)
- poj2778 DNA Sequence(AC自动机+矩阵快速幂)
- POJ2778 DNA Sequence 题解(AC自动机+矩阵快速幂)
- POJ2778 DNA Sequence (AC自动机+矩阵快速幂)
- POJ2778 DNA Sequence AC自动机+DP+矩阵快速幂
- poj2778 DNA Sequence AC自动机+矩阵快速幂
- AC自动机+快速矩阵幂 poj2778 DNA Sequence
- 【POJ2778】 DNA Sequence AC自动机+矩阵快速幂
- POJ2778 DNA Sequence AC自动机+矩阵快速幂
- 【AC自动机+矩阵快速幂】poj2778 DNA Sequence
- POJ2778 DNA Sequence(AC自动机+矩阵快速幂)
- POJ2778----AC自动机的变形+矩阵快速幂(AC自动机和矩阵快速幂必做题)
- POJ2778 AC自动机 + 矩阵
- poj2778 ac自动机+矩阵
- sap BI webi报表技巧:用户指定(自定义)排序的列
- 树莓派开发系列教程3——树莓派rasp-config配置
- Android应用程序目录结构
- PowerDesigner 简介
- STL map的简单使用
- poj2778(AC自动机+矩阵快速幂)
- Codeforces 446B DZY Loves Modification
- 通过node_id找到users并添加到数据库
- 开源企业IM-免费企业即时通讯-ENTBOOST V1.0版本发布
- [转载]思科Cisco IOS版本命名规则
- 第九章 9.5.1节练习 & 9.5.2节练习
- 移动端无痕埋点的架构及实践
- 关于Java截屏软件的开发收获
- sql判断各种类型的东西是否存在