poj 2778

AC自动机+矩阵乘法。和多数人一样。也是看了Matrix67的博客。http://www.cnblogs.com/lj030/archive/2013/05/17/3083718.html

  1 #include <iostream>
  2  #include <cstdio>
  3  #include <cstring>
  4  #include <queue>
  5  #define LL long long
  6  using namespace std;
  7  const int maxn=11;
  8  const int inf=0x3f3f3f3f;
  9  const int mod=100000;
 10  int ch[12*12][4];
 11  int val[12*12],tot,f[12*12];
 12  struct Matrix
 13  {
 14      LL g[11*11][11*11];
 15  };
 16  Matrix operator * (Matrix a,Matrix b)
 17 {
 18     int i,j,k;
 19     Matrix c;
 20     for(i=0;i<tot;i++)
 21     {
 22         for(j=0;j<tot;j++)
 23         {
 24             c.g[i][j]=0;
 25             for(k=0;k<tot;k++)
 26                 c.g[i][j]=(c.g[i][j]+a.g[i][k]*b.g[k][j])%mod;
 27         }
 28     }
 29     return c;
 30 }
 31  int getV(char c)
 32  {
 33      switch(c)
 34      {
 35      case 'A':return 0;
 36      case 'G':return 1;
 37      case 'C':return 2;
 38      case 'T':return 3;
 39      }
 40  }
 41  void Insert(char *s)
 42  {
 43      int u=0,len=strlen(s),i,tv;
 44      for(i=0;i<len;i++)
 45      {
 46          tv=getV(s[i]);
 47          if(!ch[u][tv])
 48          {
 49              memset(ch[tot],0,sizeof(ch[tot]));
 50              ch[u][tv]=tot++;
 51          }
 52          u=ch[u][tv];
 53      }
 54      val[u]=1;
 55  }
 56  void getFail()
 57  {
 58      queue<int> q;
 59      f[0]=0;
 60      int i,u;
 61      for(i=0;i<4;i++)
 62      {
 63          u=ch[0][i];
 64          if(u)
 65          {
 66              f[u]=0;
 67              q.push(u);
 68          }
 69      }
 70      int v,r;
 71      while(!q.empty())
 72      {
 73          r=q.front();q.pop();
 74          for(i=0;i<4;i++)
 75          {
 76              u=ch[r][i];
 77              if(!u) { ch[r][i]=ch[f[r]][i]; }
 78              else
 79              {
 80              if(val[r]) val[u]=1;
 81              q.push(u);
 82              v=f[r];
 83              while(v&&!ch[v][i]) v=f[v];
 84              f[u]=ch[v][i];
 85              if(val[f[u]]) val[u]=1;
 86              }
 87          }
 88      }
 89  }
 90  Matrix M_pow(Matrix tem,int n)
 91  {
 92      Matrix tem2;
 93      memset(tem2.g,0,sizeof(tem2.g));
 94      for(int i=0;i<tot;i++) tem2.g[i][i]=1;
 95      for(;n;n>>=1)
 96      {
 97          if(n&1) tem2=tem2*tem;
 98         tem=tem*tem;
 99      }
100      return tem2;
101  }
102  int main()
103  {
104      int m,n;
105      while(~scanf("%d%d",&m,&n))
106      {
107          memset(val,0,sizeof(val));
108      int i,j;
109      char s[12];
110      tot=1;
111      for(i=0;i<m;i++)
112      {
113          scanf("%s",s);
114          Insert(s);
115      }
116      getFail();
117      Matrix tem;
118      for(i=0;i<tot;i++)
119          for(j=0;j<tot;j++)
120             tem.g[i][j]=0;
121      int v;
122     for(i=0;i<tot;i++)
123     {
124         for(j=0;j<4;j++)
125         {
126            v=ch[i][j];
127            if(val[v]) continue;
128            else
129                tem.g[i][v]++;
130         }
131     }
132     Matrix ans=M_pow(tem,n);
133     int re=0;
134     for(i=0;i<tot;i++) re=re+ans.g[0][i];
135     printf("%d\n",re%mod);
136      }
137      return 0;
138  }

 

---恢复内容结束---

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值