码迷,mamicode.com
首页 > 其他好文 > 详细

[POJ2778]DNA Sequence

时间:2016-03-29 21:29:25      阅读:213      评论:0      收藏:0      [点我收藏+]

标签:

  看到n<=20亿顿时傻眼。。AC自动机上用矩阵乘法优化DP。。。sxbk

  建出AC自动机,把非法的节点去掉后求出trie图。。。

  然后根据trie图中的转移关系建矩阵。。。。最后跑个快速幂

 

  竟然搞出来了...感人肺腑

  脑子各种短路。。先是矩乘打挂,然后是trie图求措TAT。调了一整节晚自修。

技术分享
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #define ll long long
 6 using namespace std;
 7 const int modd=100000;
 8 int v[257],dl[103],fail[103],num[103];
 9 int ch[103][4],tot,next[103][4];
10 ll mp[103][103],cnt;
11 ll c[103][103],tmp[103][103],ans;
12 int i,j,k,n,m,l,r;
13 bool gg[103];
14 char s[23];
15 
16 inline void trie(int n){
17     int i,p=0;
18     for(i=0;i<n;i++){
19         if(!ch[p][v[s[i]]])ch[p][v[s[i]]]=++tot,p=tot;
20         else p=ch[p][v[s[i]]];
21     }
22     gg[p]=1;//printf("gg:  %d\n",p);
23 }
24 inline void getfail(){
25     int l=0,r=1,i,j,now,p;dl[1]=0;
26     while(l<r){
27         now=dl[++l];//printf("   %d  fail:%d    gg:%d\n",now,fail[now],gg[now]);
28         for(i=0;i<4;i++)if(ch[now][i]){
29             j=ch[now][i];//printf("  %d-->%d\n",now,j);
30             for(p=fail[now];p&&!ch[p][i];p=fail[p]);
31             if(!now)fail[j]=0;else fail[j]=ch[p][i];
32             dl[++r]=j;gg[j]|=gg[fail[j]];
33         }
34     }
35 }
36 inline void getnext(){
37     l=0,r=1;int i,now,p;dl[1]=0;
38     bool flag=0;
39     while(l<r){
40         now=dl[++l];//printf("    %d\n",now);
41         for(i=0;i<4;i++){
42             if(ch[now][i]){
43                 if(gg[ch[now][i]])next[now][i]=-1;
44                 else next[now][i]=ch[now][i],dl[++r]=ch[now][i];
45             }
46             else{
47                 for(p=fail[now];p&&!ch[p][i];p=fail[p]);
48                 next[now][i]=gg[ch[p][i]]?-1:ch[p][i];
49             }
50         //    printf("%d %d  next:%d\n",now,i,next[now][i]);
51         }
52     }
53 }
54 inline void upd(){
55     cnt=0;int i,j;
56     for(i=1;i<=r;i++)
57         num[dl[i]]=++cnt;
58     for(i=1;i<=r;i++){
59         j=dl[i];
60         for(k=0;k<4;k++)if(next[j][k]!=-1)
61             mp[num[next[j][k]]][num[j]]++;
62     }
63     
64 //    for(i=1;i<=r;puts(""),i++)
65 //        for(j=1;j<=r;j++)printf("   %lld",mp[i][j]);
66 }
67 
68 
69 inline void multoc(){
70     register int i,j,k;
71     for(i=1;i<=cnt;i++)
72     for(j=1;j<=cnt;tmp[i][j]%=modd,j++)
73         for(tmp[i][j]=0,k=1;k<=cnt;k++)tmp[i][j]+=mp[i][k]*c[k][j];
74     for(i=1;i<=cnt;i++)memcpy(c[i],tmp[i],(cnt+1)<<3);
75 }
76 inline void multomp(){
77     register int i,j,k;
78     for(i=1;i<=cnt;i++)
79     for(j=1;j<=cnt;tmp[i][j]%=modd,j++)
80         for(tmp[i][j]=0,k=1;k<=cnt;k++)tmp[i][j]+=mp[i][k]*mp[k][j];
81     for(i=1;i<=cnt;i++)memcpy(mp[i],tmp[i],(cnt+1)<<3);
82 }
83 int main(){
84     v[A]=0,v[C]=1,v[G]=2,v[T]=3;
85     
86     scanf("%d%d",&n,&m);
87     for(i=1;i<=n;i++)scanf("%s",s),trie(strlen(s));
88     getfail(),getnext(),upd();
89     for(i=1;i<=cnt;i++)c[i][i]=1;
90     
91     while(m){
92         if(m&1)
93             multoc();
94         m>>=1;if(m)multomp();
95     }
96     for(i=1,ans=0;i<=cnt;i++)ans=(ans+c[i][1])%modd;
97     printf("%lld\n",ans);
98     return 0;
99 }
View Code

 

[POJ2778]DNA Sequence

标签:

原文地址:http://www.cnblogs.com/czllgzmzl/p/5334325.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!