zoukankan      html  css  js  c++  java
  • [POJ2778]DNA Sequence

      看到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
    ",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
    ",now,fail[now],gg[now]);
    28         for(i=0;i<4;i++)if(ch[now][i]){
    29             j=ch[now][i];//printf("  %d-->%d
    ",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
    ",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
    ",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
    ",ans);
    98     return 0;
    99 }
    View Code
  • 相关阅读:
    jenkins+newman+postman实现api自动化
    数据库的关闭方法
    获取2台linux机器的时间差
    性能测试与其分析
    todo:云数据库的元信息
    todo:trove命令使用
    syslog协议及rsyslog服务全解析
    C++Primer学习日记
    excel-填充
    excel-删除
  • 原文地址:https://www.cnblogs.com/czllgzmzl/p/5334325.html
Copyright © 2011-2022 走看看