【POJ】2778 DNA Sequence(AC自动机+矩阵快速幂)

题目

传送门:QWQ

分析

对着Trie图搞快速幂。

为什么这样是对的呢?

详见:http://www.matrix67.com/blog/archives/276

有些地方还不是很理解。。。。。。为什么节点还要往下扩展?

有空再来搞一搞

代码

 1 //#include <bits/stdc++.h>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 using namespace std;
 6 typedef long long ll;
 7 const int maxn=200, MOD=100000;
 8 int son[maxn][30], fail[maxn], end[maxn],q[maxn] , newp, flag[maxn];
 9 char s[maxn];
10 struct Matrix{
11     ll m[maxn][maxn];
12     Matrix(){memset(m,0,sizeof(m));}
13 };
14 Matrix operator*(const Matrix &mat1,const Matrix &mat2){
15     Matrix m;
16     for(int i=1;i<=newp;i++)
17         for(int j=1;j<=newp;j++)
18             for(int k=1;k<=newp;k++){
19                 m.m[i][j]=(m.m[i][j]+mat1.m[i][k]*mat2.m[k][j])%MOD;
20             }
21     return m;
22 }
23 int find(int cur,int i){
24     if(!cur) return 1;
25     if(son[cur][i]) return son[cur][i];
26     return find(fail[cur],i);
27 }
28 int main(){
29     int n,L;
30     while(scanf("%d%d",&n,&L)==2){
31         int l,r;
32         memset(son,0,sizeof(son)); memset(fail,0,sizeof(fail)); memset(end,0,sizeof(end)); memset(q,0,sizeof(q));
33         newp=1;
34         for(int i=1;i<=n;i++){
35             scanf("%s",s+1);
36             int cur=1,len=strlen(s+1);
37             for(int j=1;j<=len;j++){
38                 if(!son[cur][s[j]-'A']) son[cur][s[j]-'A']=++newp;
39                 cur=son[cur][s[j]-'A'];
40             }
41             end[cur]=i; flag[cur]=1;
42         }
43 
44         Matrix ans,a;
45         for(q[l=r=1]=1;l<=r;l++){
46             for(int i=0;i<26;i++){
47                 if(son[q[l]][i]){ 
48                     fail[son[q[l]][i]]=find(fail[q[l]],i);
49                     q[++r]=son[q[l]][i];
50                 }
51                 else son[q[l]][i]=find(fail[q[l]],i);
52                 flag[son[q[l]][i]]|=flag[fail[son[q[l]][i]]];
53             }
54         }
55 
56         for(int i=1;i<=newp;i++){
57             if(flag[i]) continue;
58             for(int j=0;j<26;j++){
59                 int q=j+'A';
60                 if(((q=='A'||q=='C'||q=='G'||q=='T'))&&flag[son[i][j]]==0){
61                     a.m[i][max(son[i][j],1)]++;
62 
63                 }
64             }
65         }
66         for(int i=1;i<=newp;i++,puts(""))
67             for(int j=1;j<=newp;j++){
68                 printf("%lld ",a.m[i][j]);
69             }
70         for(int i=1;i<=newp;i++) ans.m[i][i]=1;
71         while(L){
72             if(L&1) ans=ans*a;
73             a=a*a;
74             L>>=1;
75         }
76         ll res=0;
77         for(int i=1;i<=newp;i++) res=(res+ans.m[1][i])%MOD;
78         printf("%d\n",res);
79     }
80 }
81 /*
82 5 10
83 ACGE
84 CG
85 CCGG
86 ACG
87 TTAC
88 */

猜你喜欢

转载自www.cnblogs.com/noblex/p/9385903.html