http://poj.org/problem?id=2778

题意:有m个病毒DNA,问构造一个长度为n的不带病毒DNA的字符串可以有多少种。

思路:看到这题有点懵,想了挺久题解的思路。

使用AC自动机判断总共有哪些状态,和哪些状态是不可取的。

然后构造出矩阵mat,mat[i][j]代表从状态i走到状态j走一步可以有多少种走法,然后走n步就是mat[i][j]^n(就像你走第一步可以有2种走法,走第二步可以有2^2种走法,走第三步可以有2^3种走法一样的道理(一开始还想不懂))。

在AC自动机判断状态不可取的时候,不但是插入的串末尾不可取,而且如果fail指针指向的状态是不可取的,那么当前的状态也是不可取的!因为fail指针指向的是当前匹配了的串的最长后缀,那么当前匹配了的串必定包含了fail指针指向的串(病毒串)。

还参考了很多数据==。

 #include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
#define N 105
#define TOL 4
#define MOD 100000
typedef long long LL; int sz; typedef struct Node {
Node *next[TOL];
Node *fail; int flag, id;
Node () {
for(int i = ; i < TOL; i++) next[i] = NULL;
fail = NULL; flag = ; id = sz++;
}
} node; class Matrix { public: LL mat[N][N]; void init() { memset(mat, , sizeof(mat)); } void identity() { memset(mat, , sizeof(mat)); for(int i = ; i < sz; i++) mat[i][i] = ; } static void print(Matrix now) {
printf("sz : %d\n", sz);
for(int i = ; i < sz; i++) {
for(int j = ; j < sz; j++) {
printf("%d ", now.mat[i][j]);
}
puts("");
}
} friend Matrix operator * (const Matrix &a, const Matrix &b) {
Matrix c; c.init();
for(int i = ; i < sz; i++) {
for(int k = ; k < sz; k++) {
for(int j = ; j < sz; j++) {
c.mat[i][k] = c.mat[i][k] + a.mat[i][j] * b.mat[j][k];
}
c.mat[i][k] %= MOD; // 如果放在里面会TLE
}
}
return c;
} friend Matrix operator ^ (Matrix a, int k) {
Matrix b; b.identity();
while(k) {
if(k & ) b = b * a;
a = a * a;
k >>= ;
}
return b;
} void solve(Matrix now, int n) {
now = now ^ n;
int sum = ;
for(int i = ; i < sz; i++) { sum = (sum + now.mat[][i]); if(sum >= MOD) sum -= MOD; }
printf("%d\n", sum % MOD);
}
}; class AC_DFA { private: node* root;
vector<node*> dic; public: AC_DFA() {
dic.clear();
root = new node();
sz = ; dic.push_back(root);
} ~AC_DFA() {
for(int i = ; i < sz; i++) delete dic[i];
} int get(char c) {
if(c == 'A') return ;
if(c == 'C') return ;
if(c == 'G') return ;
return ;
} void insert(char *s) {
node* now = root;
int len = strlen(s);
for(int i = ; i < len; i++) {
int c = get(s[i]);
if(now->next[c] == NULL) now->next[c] = new node(), dic.push_back(now->next[c]);
now = now->next[c];
}
now->flag = ;
} void build() {
queue<node*> que;
root->fail = NULL;
que.push(root);
while(!que.empty()) {
node* now = que.front(); que.pop();
for(int i = ; i < TOL; i++) {
if(now->next[i]) {
node* p = now->fail;
while(p && p->next[i] == NULL) p = p->fail;
// 如果指向的fail是病毒,那么now->next[i]也是带病毒的,因为指向的fail是其最大后缀
if(p) now->next[i]->fail = p->next[i], now->next[i]->flag |= p->next[i]->flag;
else now->next[i]->fail = root;
que.push(now->next[i]);
} else {
if(now == root) now->next[i] = root;
else now->next[i] = now->fail->next[i];
}
}
}
} Matrix buildMatrix() {
Matrix a; a.init();
for(int i = ; i < dic.size(); i++) {
for(int j = ; j < TOL; j++) {
if(dic[i]->next[j]->flag == ) {
int tmp = dic[i]->next[j]->id;
a.mat[i][tmp]++;
}
}
}
return a;
}
}; int main() {
int m, n;
scanf("%d%d", &m, &n);
char s[N];
AC_DFA ac;
for(int i = ; i < m; i++)
scanf("%s", s), ac.insert(s);
ac.build();
Matrix now = ac.buildMatrix();
now.solve(now, n);
return ;
} /*
4 3
AT
AC
AG
AA
10 100
AGAGAGT
CGTATTG
AAAATTTCGC
GCGTA
TCGA
AATTGGA
TAGATAGC
AGCGTATT
TTCGA
TACGTATTG
3 10
AT
GATC
TGAC
48233
*/

POJ 2778:DNA Sequence(AC自动机构造矩阵)的更多相关文章

  1. poj 2778 DNA Sequence AC自动机DP 矩阵优化

    DNA Sequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11860   Accepted: 4527 Des ...

  2. POJ 2778 DNA Sequence (AC自动机+DP+矩阵)

    题意:给定一些串,然后让你构造出一个长度为 m 的串,并且不包含以上串,问你有多少个. 析:很明显,如果 m 小的话 ,直接可以用DP来解决,但是 m 太大了,我们可以认为是在AC自动机图中,根据离散 ...

  3. poj 2778 DNA Sequence ac自动机+矩阵快速幂

    链接:http://poj.org/problem?id=2778 题意:给定不超过10串,每串长度不超过10的灾难基因:问在之后给定的长度不超过2e9的基因长度中不包含灾难基因的基因有多少中? DN ...

  4. POJ 2778 DNA Sequence (AC自动机,矩阵乘法)

    题意:给定n个不能出现的模式串,给定一个长度m,要求长度为m的合法串有多少种. 思路:用AC自动机,利用AC自动机上的节点做矩阵乘法. #include<iostream> #includ ...

  5. POJ 2778 DNA Sequence ( AC自动机、Trie图、矩阵快速幂、DP )

    题意 : 给出一些病毒串,问你由ATGC构成的长度为 n 且不包含这些病毒串的个数有多少个 分析 : 这题搞了我真特么久啊,首先你需要知道的前置技能包括 AC自动机.构建Trie图.矩阵快速幂,其中矩 ...

  6. poj 2778 DNA Sequence AC自动机

    DNA Sequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11860   Accepted: 4527 Des ...

  7. POJ 2778 DNA Sequence (AC自己主动机 + dp)

    DNA Sequence 题意:DNA的序列由ACTG四个字母组成,如今给定m个不可行的序列.问随机构成的长度为n的序列中.有多少种序列是可行的(仅仅要包括一个不可行序列便不可行).个数非常大.对10 ...

  8. POJ 2778 DNA Sequence ( Trie图、矩阵快速幂 )

    题意 : 给出一些病毒串,问你由ATGC构成的长度为 n 且不包含这些病毒串的个数有多少个 分析: 我们先分析Tire 图的结构 : Trie图是在AC自动机的原型上增添边使得状态可以快速转移,标记危 ...

  9. [poj2778 DNA Sequence]AC自动机,矩阵快速幂

    题意:给一些字符串的集合S和整数n,求满足 长度为n 只含charset = {'A'.'T‘.'G'.'C'}包含的字符 不包含S中任一字符串 的字符串的种类数. 思路:首先对S建立ac自动机,考虑 ...

  10. 2018 焦作网络赛 L Poor God Water ( AC自动机构造矩阵、BM求线性递推、手动构造矩阵、矩阵快速幂 )

    题目链接 题意 : 实际上可以转化一下题意 要求求出用三个不同元素的字符集例如 { 'A' .'B' .'C' } 构造出长度为 n 且不包含 AAA.BBB CCC.ACB BCA.CAC CBC ...

随机推荐

  1. 图形化界面安装oracle报错Could not execute auto check for display colors using command /usr/bin/xdpyinfo. Check if the DISPLAY variable is set.

    问题描述: 在Linux + oracle 安装时,采有root 帐号登录x-windows 界面,然后 $su oracle 登录录安装Oracle 报以下错误: >>> Coul ...

  2. WCF 大文件传输配置

    <bindings> <webHttpBinding> <!--这个是接收大数据加的,设置WCF服务器端数据接收上限参数,此处单位字节,故2147483647字节==2G ...

  3. 特殊存储过程——触发器Trigger

    触发器类型 insert 触发器delete 触发器update 触发器 Inserted和Deleted两个临时表的作用 Inserted:对于插入记录操作来说,插入表里存放的是要插入的数据:对于更 ...

  4. 关于 IIS 上运行 ASP.NET Core 站点的“HTTP 错误 500.19”错误

    昨天回答了博问中的一个问题 —— “HTTP 错误 500.19 - Internal Server Error dotnetcore”,今天在这篇随笔中时候事后诸葛亮地小结一下. 服务器是 Wind ...

  5. Template简介

    分类   ControlTemplate ItemsPanelTemplate DataTemplate 样式Style和模板Template对比 Style:样式,风格Template:模版,某种控 ...

  6. socket 主机地址相关的函数

    #include <arpa/inet.h> int inet_aton (const char *name, struct in_addr *addr) 将ipv4地址从数字点的形式转化 ...

  7. MVC 直接或间接继承自ActionResult的类型

    •ViewResult:使用View()可以指定一个页面,也可以指定传递的模型对象,如果没有指定参数则表示返回与Action同名的页面 •ContentResult:使用Content(string ...

  8. Installshield 在安装或者卸载过程中,判断某一程序是否正在运行

    1.在操作时,首先引入类库ShutDownRunningApp.rul,其中ShutDownRunningApp.rul代码如下 /////////////////////////////////// ...

  9. laravel在wamp中输入地址后总是无法访问

    在wamp中的apache中conf的httpd.conf #LoadModule rewrite_module modules/mod_rewrite.so 改为 LoadModule rewrit ...

  10. 使用BGP的虚拟下一跳实现IGP的路由负载

    网络拓扑: XRV1 ============================================================== !hostname XRV1! interface ...