• POJ


    题目连接:https://vjudge.net/problem/POJ-2778

    题意:给m个病毒串,问不包含病毒串且长度n的DNA片段有几个。

    题解:我看了好多个题解讲的都不是很清楚,终于找到一个看明白的了。

    https://blog.csdn.net/morgan_xww/article/details/7834801

    (1)用病毒串构造一个AC自动机,病毒串末尾的结点要标记,如果当前结点fail指向的结点被标记了,那么当前节点也要被标记。

    (2)用AC自动机构造矩阵a,表示到达某个状态的合法转移次数。

    (3)求矩阵的n次幂,第0行的和即为结果;

      1 #include<iostream>
      2 #include<algorithm>
      3 #include<queue>
      4 #include<string.h>
      5 #define ll long long
      6 using namespace std;
      7 
      8 const ll mod=1e5;
      9 const ll maxn = 111;
     10 const ll MX = 111;
     11 ll ans=0;
     12 ll d['Z'+1];
     13 
     14 struct tire{
     15     ll nxt[maxn][4],fail[maxn],end[maxn],tot,root,vis[maxn];
     16     ll newNode(){
     17         for(ll i=0;i<4;i++) nxt[tot][i] = -1;
     18         end[tot++] = 0;
     19         return tot-1;
     20     }
     21     void Init(){
     22         tot = 0;
     23         root = newNode();
     24         ans=0;
     25     }
     26     void Insert(char *buf){
     27         ll len = strlen(buf),i,u = root;
     28         for(i=0;i<len;i++){
     29             ll x = d[buf[i]];
     30             if(nxt[u][x]==-1) nxt[u][x] = newNode();
     31             u = nxt[u][x];
     32         }
     33         end[u] = 1;
     34     }
     35     void build(){
     36         queue <ll> q;
     37         fail[root] = root;
     38         for(ll i=0;i<4;i++){
     39             if(nxt[root][i]==-1) nxt[root][i] = root;
     40             else{
     41                 fail[nxt[root][i]] = root;
     42                 q.push(nxt[root][i]);
     43             }
     44             end[nxt[root][i]]|=end[fail[nxt[root][i]]];
     45         }
     46         while(!q.empty()){
     47             ll now = q.front();
     48             q.pop();
     49             for(ll i=0;i<4;i++){
     50                 if(nxt[now][i]==-1) nxt[now][i] = nxt[fail[now]][i];
     51                 else{
     52                     fail[nxt[now][i]] = nxt[fail[now]][i];
     53                     q.push(nxt[now][i]);
     54                 }
     55                 end[nxt[now][i]]|=end[fail[nxt[now][i]]];
     56             }
     57         }
     58     }
     59 }ac;
     60 
     61 struct Mat{
     62     ll mat[maxn][maxn];
     63 };
     64 
     65 Mat operator * (Mat a, Mat b) {
     66     Mat c;
     67     ll i, j, k;
     68     memset(c.mat, 0, sizeof(c.mat));
     69     for (i = 0; i <= ac.tot; i++)
     70         for (j = 0; j <= ac.tot; j++)
     71             for (k = 0; k <= ac.tot; k++) {
     72                 c.mat[i][j] += a.mat[i][k] * b.mat[k][j];
     73                 c.mat[i][j] %= mod;
     74             }
     75     return c;
     76 }
     77 
     78 Mat operator ^ (Mat a, ll b) {
     79     Mat c;
     80     ll i, j;
     81     for (i = 0; i <= ac.tot; i++)
     82         for (j = 0; j <= ac.tot; j++)
     83             c.mat[i][j] = (i == j);
     84     while(b != 0) {
     85         if (b & 1 != 0) c = c * a;
     86             a = a * a;
     87             b /= 2;
     88     }
     89     return c;
     90 }
     91 
     92 char s1[MX];
     93 
     94 int main()
     95 {
     96     ios::sync_with_stdio(false);
     97     cin.tie(0);
     98     cout.tie(0);
     99     ll t,n,m;
    100     cin>>n>>m;
    101     d['A']=0,d['C']=1,d['T']=2,d['G']=3;
    102     ac.Init();
    103     for(ll i=0;i<n;i++) cin>>s1,ac.Insert(s1);
    104     ac.build();
    105     Mat a,b;
    106     for(ll i=0;i<=ac.tot;i++){
    107         if(ac.end[i]) continue;
    108         for(ll j=0;j<4;j++){
    109             if(ac.end[ac.nxt[i][j]]) continue;
    110             a.mat[i][ac.nxt[i][j]]++;
    111         }
    112     }
    113     b=a^m;
    114     for(ll i=0;i<=ac.tot;i++){
    115         ans+=b.mat[0][i];
    116         ans%=mod;
    117     }
    118     cout<<ans<<endl;
    119     return 0;
    120 }
  • 相关阅读:
    win32下使用相对exe文件的绝对路径资源
    修改Unity中Lua文件的默认打开程序
    Unity中巧用协程和游戏对象的生命周期处理游戏重启的问题
    Unity3D MonoBehaviour的生命周期(lifecycle)
    使用Doxygen + graphviz生成Unity 3d的UGUI类图
    IEEE 754二进制浮点数算术标准
    foxmail同步QQ邮箱里的所有文件夹
    Windows下的搜索神器 —— everything
    electron实现类似QQ来新消息时的闪烁与任务栏窗口提醒
    iOS 10.3下使用Fiddler抓取HTTPS请求
  • 原文地址:https://www.cnblogs.com/lilibuxiangtle/p/12488196.html
Copyright © 2020-2023  润新知