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

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<queue>
 4 using namespace std;
 5 typedef long long ll;
 6 const char* ss="ATCG";
 7 const int N=100+10,M=4,mod=100000;
 8 int m,n;
 9 char s[N];
10 struct Mat {
11     int a[N][N],n;
12     int* operator[](int x) {return a[x];}
13     Mat(int x) {memset(a,0,sizeof a),n=x;}
14     Mat operator+(Mat b) {
15         Mat c(n);
16         for(int i=0; i<n; ++i)
17             for(int j=0; j<n; ++j)c[i][j]=(a[i][j]+b[i][j])%mod;
18         return c;
19     }
20     Mat operator*(Mat b)const {
21         Mat c(n);
22         for(int k=0; k<n; ++k)
23             for(int i=0; i<n; ++i)
24                 for(int j=0; j<n; ++j)c[i][j]=(c[i][j]+(ll)a[i][k]*b[k][j])%mod;
25         return c;
26     }
27 };
28 Mat Pow(Mat x,int p) {
29     Mat ret(x.n);
30     for(int i=0; i<x.n; ++i)ret[i][i]=1;
31     for(; p; p>>=1,x=x*x)if(p&1)ret=ret*x;
32     return ret;
33 }
34 struct AC {
35     int go[N][M],pre[N],end[N],tot;
36     int idx(char ch) {
37         if(ch=='A')return 0;
38         if(ch=='T')return 1;
39         if(ch=='C')return 2;
40         if(ch=='G')return 3;
41         return -1;
42     }
43     int newnode() {int u=tot++; pre[u]=end[u]=0,memset(go[u],0,sizeof go[u]); return u;}
44     void init() {tot=0,newnode();}
45     void ins(char* s,int n) {
46         int u=0;
47         for(int i=0; i<n; u=go[u][idx(s[i])],++i)
48             if(!go[u][idx(s[i])])go[u][idx(s[i])]=newnode();
49         end[u]=1;
50     }
51     void build() {
52         queue<int> q;
53         for(int i=0; i<M; ++i)if(go[0][i])q.push(go[0][i]);
54         while(q.size()) {
55             int u=q.front();
56             q.pop();
57             end[u]|=end[pre[u]];
58             for(int i=0; i<M; ++i) {
59                 if(go[u][i])pre[go[u][i]]=go[pre[u]][i],q.push(go[u][i]);
60                 else go[u][i]=go[pre[u]][i];
61             }
62         }
63     }
64     Mat getmat() {
65         Mat ret(tot);
66         for(int i=0; i<tot; ++i)
67             for(int j=0; j<M; ++j)if(!end[go[i][j]])ret[go[i][j]][i]++;
68         return ret;
69     }
70 } ac;
71 int main() {
72     ac.init();
73     scanf("%d%d",&m,&n);
74     while(m--)scanf("%s",s),ac.ins(s,strlen(s));
75     ac.build();
76     Mat x=ac.getmat();
77     x=Pow(x,n);
78     int ans=0;
79     for(int i=0; i<x.n; ++i)ans=(ans+x[i][0])%mod;
80     printf("%d\n",ans);
81     return 0;
82 }

猜你喜欢

转载自www.cnblogs.com/asdfsag/p/10841808.html