zoukankan      html  css  js  c++  java
  • poj_2778_DNA Sequence(AC自动机+矩阵)

    题目链接:poj_2778_DNA Sequence

    题意:

    有m个模式串,然后给你一个长度n,问你n长度的DNA序列有多少种不包含这m个模式串

    题解:

    这题显然要用AC自动机,将模式串的AC自动机建好后,再构建矩阵,矩阵的含义是自动机中0~tot的节点走一步到0~tot的节点的方案数,然后要走n步,所以上一个矩阵快速幂就行了,在建AC自动机的时候要改变一下失败指针的指向,不存在的节点就指向当前节点的失败指针,这样就模拟了AC自动机的匹配过程,需要画图好好理解一下。

     1 #include<cstdio>
     2 #include<cstring>
     3 #define mst(a,b) memset(a,b,sizeof(a))
     4 #define F(i,a,b) for(int i=a;i<=b;i++)
     5 typedef long long ll;
     6 //-----------------------矩阵-------------------------
     7 const int mat_N=11*11+7,mo=1e5;//矩阵阶数,取膜
     8 int N;
     9 struct mat{
    10     ll c[mat_N][mat_N];
    11     void init(){mst(c,0);}
    12     mat operator*(mat b){
    13         mat M;M.init();
    14         F(i,0,N)F(j,0,N)F(k,0,N)M.c[i][j]=(M.c[i][j]+c[i][k]*b.c[k][j])%mo;
    15         return M;
    16     }
    17     mat operator+(mat b){
    18         mat M;
    19         F(i,0,N)F(j,0,N)M.c[i][j]=(c[i][j]+b.c[i][j])%mo;
    20         return M;
    21     }
    22     mat operator^(ll k){
    23         mat ans,M=(*this);ans.init();
    24         F(i,0,N)ans.c[i][i]=1;
    25         while(k){if(k&1)ans=ans*M;k>>=1,M=M*M;}
    26         return ans;
    27     }
    28 }A;
    29 //-----------------------AC自动机-----------------------
    30 const int AC_N=11*11,tyn=4;//数量乘串长,类型数
    31 struct AC_automation{
    32     int tr[AC_N][tyn],cnt[AC_N],Q[AC_N],fail[AC_N],tot;
    33     inline int getid(char x){
    34         if(x=='A')return 0;
    35         if(x=='T')return 1;
    36         if(x=='G')return 2;
    37         if(x=='C')return 3;
    38     }
    39     void nw(){cnt[++tot]=0;memset(tr[tot],-1,sizeof(tr[tot]));}
    40     void init(){tot=-1,fail[0]=-1,nw();}
    41     void insert(char *s,int x=0){
    42         for(int len=strlen(s),i=0,w;i<len;x=tr[x][w],i++)
    43             if(tr[x][w=getid(s[i])]==-1)nw(),tr[x][w]=tot;
    44         cnt[x]++;//串尾标记
    45     }
    46     void build(int head=1,int tail=0){
    47         for(Q[++tail]=0;head<=tail;){
    48             for(int i=0,x=Q[head++],p=-1;i<tyn;i++)if(~tr[x][i]){
    49                 if(x==0)fail[tr[0][i]]=0;
    50                 else for(p=fail[x],fail[tr[x][i]]=0;~p;p=fail[p])
    51                         if(~tr[p][i]){fail[tr[x][i]]=tr[p][i];break;}
    52                 if(cnt[fail[tr[x][i]]])cnt[tr[x][i]]=1;
    53                 Q[++tail]=tr[x][i];
    54             }else if(x==0)tr[x][i]=0;
    55             else tr[x][i]=tr[fail[x]][i];
    56         }
    57     }
    58 }AC;
    59 
    60 void build_mat()
    61 {
    62     A.init();
    63     F(i,0,AC.tot)F(j,0,3)if(!AC.cnt[i]&&!AC.cnt[AC.tr[i][j]])A.c[i][AC.tr[i][j]]++;
    64 }
    65 
    66 int main()
    67 {
    68     ll n,m,ans;char buf[30];
    69     while(~scanf("%lld%lld",&n,&m))
    70     {
    71         AC.init();
    72         F(i,1,n)scanf("%s",buf),AC.insert(buf);
    73         AC.build(),N=AC.tot,build_mat(),A=A^m,ans=0;
    74         F(i,0,AC.tot)ans+=A.c[0][i];
    75         printf("%lld
    ",ans%mo);
    76     }
    77     return 0;
    78 }
    View Code
  • 相关阅读:
    Freemaker:操作集合
    win10:在关闭防火墙下如何屏蔽特定端口
    win10:家庭版开启组策略
    oracle:10g下载地址(转载)
    mybatis:延迟加载时不要在get/set方法上面添加final关键字(原创)
    mybatis:在springboot中的配置
    mybatis:访问静态变量或方法
    maven:手动安装JAR到本地仓库
    datatables日常使用集合
    python 装饰器
  • 原文地址:https://www.cnblogs.com/bin-gege/p/5710734.html
Copyright © 2011-2022 走看看