ac自动机、矩阵乘法
来源:互联网 发布:java架构师 实战篇 编辑:程序博客网 时间:2024/05/21 15:25
#include <iostream>#include <cstdio>#include <algorithm>#include <cmath>#include <cstring>#include <string.h>#include <vector>#include <queue>#define mod 100000#define LL long long //poj2778 ac自动机、矩阵乘法(构建矩阵--关键)using namespace std;int k;struct node //定义静态字典树{ int isword; int next[4]; int fail; //定义失败指针 void init() { for(int t=0; t<4; ++t) { next[t]=0; } fail=-1; isword=0; }}a[110];int check(char c){ if(c=='A')return 0; if(c=='T')return 1; if(c=='C')return 2; if(c=='G')return 3;}int newnode(){ a[k].init(); return k;}void insert(char *p) //建树{ int t, j, g=0, h; //g=0表示根 j=strlen(p); for(t=0; t<j; ++t) { h=check(p[t]); //将字符转化为相应的数字 if(!a[g].next[h]) { a[g].next[h]=newnode();k++; } g=a[g].next[h]; } a[g].isword=1; //结尾标记 return ;}void acAutomation() //构建失败指针fail{ int t; queue<int> q;q.push(0);while(!q.empty()) { int s=q.front();q.pop(); for(t=0; t<4; ++t) { if(a[s].next[t]==0) { if(s==0) a[s].next[t]=0; else a[s].next[t]=a[a[s].fail].next[t]; //不是根节点的话就是s节点的fail所指的节点的next[t]位置 } else { if(s==0) { a[a[s].next[t]].fail=0; } else { int temp=a[s].fail; while(temp!=-1) { if(a[temp].next[t]) { a[a[s].next[t]].fail=a[temp].next[t]; a[a[s].next[t]].isword|=a[a[temp].next[t]].isword; //a[s].next[t]的最大后缀就是a[a[temp].fail].next[t]前缀,如果a[a[temp].fail].next[t]有标记,则a[s].next[t]也要标上 break; } temp=a[temp].fail; } if(temp==-1) //到根节点也找不到对应的next { a[a[s].next[t]].fail=0; } } q.push(a[s].next[t]); } } } return ;}struct matrix{ LL b[105][105]; //防止溢出 void init() {int t, j; for(j=0; j<105; ++j) { for(t=0; t<105; ++t) b[j][t]=0; } }matrix operator*(matrix a1) //重载可以减少内存,但速度会慢点{matrix q;q.init();int j, t, g;for(j=0; j<k; ++j){for(t=0; t<k; ++t){for(g=0; g<k; ++g){q.b[j][t]+=b[j][g]*a1.b[g][t];q.b[j][t]%=mod;}}}return q;}}p;/*matrix mul(matrix a1, matrix b1) //内存会溢出{ matrix q; q.init();int j, t, g; for(j=0; j<k; ++j) { for(int t=0; t<k; ++t) { for(int g=0; g<k; ++g) { q.b[j][t]+=a1.b[j][g]*b1.b[g][t]; q.b[j][t]%=mod; } } } return q;}*/matrix f(int x) //矩阵快速幂{ matrix q, s=p; int j, t; for(j=0; j<k; ++j) { for(t=0; t<k; ++t) { if(j==t) q.b[j][t]=1; else q.b[j][t]=0; } }while(x){if(x&1)q=q*s;x=x>>1;s=s*s;}return q;} int main(){ int n, m, t, j, g; char q[15];scanf("%d%d", &m, &n); a[0].init(); k=1; for(t=0; t<m; ++t) { scanf("%s", q); insert(q); } acAutomation();p.init();for(j=0; j<k; ++j) //构建无病毒的矩阵{if(a[j].isword)continue;for(t=0; t<4; ++t){g=a[j].next[t];if(a[g].isword)continue;p.b[j][g]++;}}matrix result=f(n); //矩阵快速幂LL ans;for(t=0, ans=0; t<k; ++t) //统计数目{ans+=result.b[0][t];}printf("%I64d\n", ans%mod);return 0;}
0 0
- ac自动机、矩阵乘法
- HDU2243-----AC自动机+矩阵乘法+矩阵公式
- POJ 2778 AC自动机+矩阵乘法
- Poj 2778 [AC自动机,矩阵乘法]
- poj 2778 AC自动机+矩阵乘法
- hdu2243之AC自动机+矩阵乘法
- 【POJ2778】AC自动机,DP,矩阵乘法
- bzoj2553 禁忌 AC自动机&矩阵乘法
- 【bzoj2553】【beijing2008】【禁忌】【AC自动机+矩阵乘法】
- poj 2778 ac自动机+矩阵乘法
- poj2778 DNA Sequence AC自动机+矩阵乘法
- Poj 2778 [AC自动机,矩阵乘法]
- poj 2778 DNA Sequence //AC自动机+矩阵乘法
- POJ2778 - AC自动机+非递归的矩阵乘法
- hdu 2243 poj 2778 AC自动机 + 经典矩阵乘法
- PKU 2778 HDU 2243 AC自动机 + 矩阵乘法
- 【poj2778】【AC自动机】【DFA】【矩阵乘法】DNA Sequence
- BZOJ 2553 BeiJing2011 禁忌 AC自动机+矩阵乘法
- 项目视频讲解_基于OpenJPA实战百度文库项目(FlexPaperViewer在线预览、文件在线转换)
- jdk的环境变量的配置
- 构建maven项目
- 设计模式 经典书籍必备推荐
- 如何减少silverlight XAP包的尺寸
- ac自动机、矩阵乘法
- MPI实现有向图所有点间最短路径
- Android Navigation Drawer(导航抽屉)
- JDBC
- 如何判断照片曝光是否准确?
- Yaffs2根文件系统制作
- 纯C语言写的编译器
- 基本语言细节--指针与引用
- java(19) - 反射机制