poj 2778 AC自动机+矩阵乘法
来源:互联网 发布:ping 域名ip 编辑:程序博客网 时间:2024/05/21 11:12
首先利用病毒串建立tire图,没个节点代表某种后缀,然后利用AC自动机对各个后缀进行转移,得到一个矩阵,然后利用快速幂求解矩阵连乘。
#include<stdio.h>#include<algorithm>#include<string.h>#include<iostream>using namespace std;const int nMax=105;const int S_NUM=4;const int N_NUM=105;const int M=100000;struct Tree{ int index,flag; Tree *fail,*next[S_NUM];}t[nMax],*Q[nMax];struct Mat{long long mat[N_NUM][N_NUM];int n,m;void init(int r,int c){n=r;m=c;}void init_e(){for(int i=0;i<n;i++)for(int j=0;j<m;j++)mat[i][j]=(i==j);}};int cnt,L,C;long long a[N_NUM][N_NUM];char key[20];Tree *root;int get(char c){ if(c=='A') return 0; else if(c=='G') return 1; else if(c=='C') return 2; else return 3;}Tree* new_node(){ Tree *p=&t[cnt]; p->index=cnt++; p->flag=0; memset(p->next,0,sizeof(p->next)); return p;}void insert(char s[]){ Tree *p=root; for(int i=0;s[i];i++) { int index=get(s[i]); if(p->next[index]==NULL) p->next[index]=new_node(); p=p->next[index]; } p->flag=1;}void build_ac(){ int f=0,r=-1; Q[++r]=root; while(f<=r) { Tree *p=Q[f++]; for(int i=0;i<S_NUM;i++) { if(p->next[i]!=NULL) { if(p==root) p->next[i]->fail=root; else { p->next[i]->fail=p->fail->next[i]; if(p->fail->next[i]->flag!=0) p->next[i]->flag=1; } Q[++r]=p->next[i]; } else { if(p==root) p->next[i]=root; else p->next[i]=p->fail->next[i]; } if(p->next[i]->flag==0) a[p->index][p->next[i]->index]++; } }}Mat Mul(Mat a,Mat b){Mat ret;ret.init(a.n,b.m);memset(ret.mat,0,sizeof(ret.mat));for(int i=0;i<a.n;i++)for(int j=0;j<b.m;j++)for(int k=0;k<b.n;k++){ret.mat[i][j]+=a.mat[i][k]*b.mat[k][j];if(ret.mat[i][j]>M) ret.mat[i][j]%=M;}return ret;}Mat exp(Mat a,int k){Mat ret=a,tmp=a;ret.init_e();for(;k;k>>=1){if(k&1){ret=Mul(ret,tmp);}tmp=Mul(tmp,tmp);}return ret;}int main(){// freopen("test.txt","r",stdin); scanf("%d%d",&L,&C); cnt=0;root=new_node(); for(int i=0;i<L;i++) { scanf("%s",key); insert(key); } build_ac(); Mat b; b.init(cnt,cnt); memcpy(b.mat,a,sizeof(a)); Mat ans=exp(b,C); int res=0; for(int i=0;i<cnt;i++) res=(res+ans.mat[0][i])%M; printf("%d\n",res); return 0;}
- POJ 2778 AC自动机+矩阵乘法
- Poj 2778 [AC自动机,矩阵乘法]
- poj 2778 AC自动机+矩阵乘法
- poj 2778 ac自动机+矩阵乘法
- Poj 2778 [AC自动机,矩阵乘法]
- poj 2778 DNA Sequence //AC自动机+矩阵乘法
- hdu 2243 poj 2778 AC自动机 + 经典矩阵乘法
- POJ 2778-DNA Sequence(AC自动机+矩阵乘法)
- ac自动机、矩阵乘法
- ac自动机+矩阵 poj 2778
- POJ-2778-ac自动机+矩阵
- poj 2778(AC自动机+矩阵)
- POJ 2778 DNA Sequence(AC自动机+矩阵)
- poj 2778 AC自动机+矩阵快速幂
- poj 2778 AC 自动机 + 矩阵快速幂
- poj 2778 ac自动机+矩阵相乘
- POJ 2778 ac自动机+矩阵快速幂
- POJ 2778 AC自动机+矩阵相乘
- HDU2818:Building Block
- java.lang.NoSuchMethodError: org.objectweb.asm.ClassWriter.<init>(Z
- keytool程序简介
- Spring security认证与授权(三)
- Java(HashCode应用和框架概念)
- poj 2778 AC自动机+矩阵乘法
- 项目管理知识笔记六:计算完工估算EAC
- ssh2项目中,使用HibernateDaoSupport异常:'sessionFactory' or 'hibernateTemplate' is required
- java 中jdbc的使用练习-错误 mysql access denied for user odbc @localhost
- VC自定义资源
- 关于删除字符串中重复字符问题?解析
- Spring security认证与授权(四)
- session与cookie的区别
- 谷歌微软逼宫!亚马逊能否保住云计算王座?