• poj2778DNA Sequence (AC自动机+矩阵快速幂)


    转载请注明出处: http://www.cnblogs.com/fraud/           ——by fraud

    DNA Sequence
    Time Limit: 1000MS   Memory Limit: 65536K

    Description

    It's well known that DNA Sequence is a sequence only contains A, C, T and G, and it's very useful to analyze a segment of DNA Sequence,For example, if a animal's DNA sequence contains segment ATC then it may mean that the animal may have a genetic disease. Until now scientists have found several those segments, the problem is how many kinds of DNA sequences of a species don't contain those segments.

    Suppose that DNA sequences of a species is a sequence that consist of A, C, T and G,and the length of sequences is a given integer n.

    Input

    First line contains two integer m (0 <= m <= 10), n (1 <= n <=2000000000). Here, m is the number of genetic disease segment, and n is the length of sequences.

    Next m lines each line contain a DNA genetic disease segment, and length of these segments is not larger than 10.

    Output

    An integer, the number of DNA sequences, mod 100000.

    Sample Input

    4 3
    AT
    AC
    AG
    AA
    

    Sample Output

    36

    Source

     
    题意
    构造一个长度为n的DNA序列,要求其中不得出现m个禁止的字符串中的任意一个
    一道很明显的矩阵快速幂的题。先通过AC自动机得出一个邻接矩阵,然后快速幂。
      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdio>
      4 #include <queue>
      5 using namespace std;
      6 #define REP(A,X) for(int A=0;A<X;A++)
      7 #define MAXN    100010
      8 
      9 int p[MAXN][4];
     10 int tail[MAXN];
     11 int fail[MAXN];
     12 int root,tot;
     13 const long long MOD =100000;
     14 struct Matrix{
     15     int n;
     16     int mat[110][110];
     17     Matrix(){}
     18     Matrix(int _n){
     19         n=_n;
     20         REP(i,n)
     21             REP(j,n)mat[i][j]=0;
     22     }
     23     void init()
     24     {
     25         REP(i,tot)
     26         REP(j,tot)mat[i][j]=0;
     27     }
     28     void unit()
     29     {
     30         REP(i,tot)
     31         REP(j,tot)mat[i][j]=i==j?1:0;
     32     }
     33     Matrix operator *(const Matrix &a)const {
     34         Matrix ret(n);
     35         REP(i,n)
     36         REP(j,n)
     37         REP(k,n)
     38         {
     39             int tmp=(long long)mat[i][k]*a.mat[k][j]%MOD;
     40             ret.mat[i][j]=(ret.mat[i][j]+tmp)%MOD;
     41         }
     42         return ret;
     43     }
     44 };
     45 int newnode()
     46 {
     47     REP(i,4)p[tot][i]=-1;
     48     tail[tot++]=0;
     49     return tot-1;
     50 }
     51 void init()
     52 {
     53     tot=0;
     54     root=newnode();
     55 }
     56 int a[MAXN];
     57 void insert(char *s){
     58     int len=strlen(s);
     59     REP(i,len)
     60     {
     61         if(s[i]=='A')a[i]=0;
     62         else if(s[i]=='C')a[i]=1;
     63         else if(s[i]=='G')a[i]=2;
     64         else if(s[i]=='T')a[i]=3;
     65     }
     66     int now= root ;
     67     REP(i,len)
     68     {
     69         if(p[now][a[i]]==-1)p[now][a[i]]=newnode();
     70         now=p[now][a[i]];
     71     }
     72     tail[now]++;
     73 }
     74 void build()
     75 {
     76     int now=root;
     77     queue<int >q;
     78     fail[root]=root;
     79     REP(i,4){
     80         if(p[root][i]==-1){
     81             p[root][i]=root;
     82         }
     83         else {
     84             fail[p[root][i]]=root;
     85             q.push(p[root][i]);
     86         }
     87     }
     88     while(!q.empty())
     89     {
     90         now =q.front();
     91         q.pop();
     92         if(tail[fail[now]])tail[now]=1;
     93         REP(i,4){
     94             if(p[now][i]==-1){
     95                 p[now][i]=p[fail[now]][i];
     96             }else{
     97                 fail[p[now][i]]=p[fail[now]][i];
     98                 q.push(p[now][i]);
     99             }
    100         }
    101     }
    102 }
    103 char s[MAXN];
    104 Matrix Mat;
    105 int main()
    106 {
    107     ios::sync_with_stdio(false);
    108     int n,m;
    109     while(cin>>m>>n){
    110         init();
    111         REP(i,m){
    112             cin>>s;
    113             insert(s);
    114         }
    115         build();
    116         Mat.n=tot;
    117         Mat.init();
    118         REP(i,tot){
    119             REP(j,4){
    120                 if(!tail[p[i][j]])Mat.mat[i][p[i][j]]++;
    121             }
    122         }
    123         Matrix tmp(tot);
    124         tmp.unit();
    125         while(n){
    126             if(n&1)tmp=tmp*Mat;
    127             Mat=Mat*Mat;
    128             n>>=1;
    129         }
    130         int ans=0;
    131         REP(i,tot)ans+=tmp.mat[0][i];
    132         ans%=MOD;
    133         cout<<ans<<endl;
    134 
    135     }
    136     return 0;
    137 }
    代码君
     
  • 相关阅读:
    异常 中断 陷阱
    关于delete字符串 需不需要加 [ ]
    关于联合体输出的问题(是否小端模式)
    String reorder
    数据库 ---5 索引 创建用户及授权 数据备份
    数据库 --- 4 多表查询 ,Navicat工具 , pymysql模块
    数据库 --- 3 行(记录)操作 单表查询
    数据库 --- 2 库 ,表
    数据库 --- 1 初始 数据库
    并发 --- 5 线程的其他方法 线程队列 线程池 协程
  • 原文地址:https://www.cnblogs.com/fraud/p/4338491.html
Copyright © 2020-2023  润新知