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. WPF与缓动(三) 指数缓动

    原文:WPF与缓动(三) 指数缓动 WPF与缓动(三) 指数缓动                                                                     ...

  2. win7(64bit)使用mingw64配置gtkmm

    因为linux命令不熟悉,加上时间不充裕,仍然决定在win7_64bit下开发GUI程序,选择gtkmm是因为: 1. 在图形界面程序中,windows系统当之无愧GUI之王,用户友好性其他OS无法替 ...

  3. C#调用JS

    cmd调用phantomjs 官方资料:http://phantomjs.org/quick-start.html 手动执行 从官方下载phantomjs.exe,拷贝它与要执行的js同目录打开cmd ...

  4. Math.Round四舍五入说明

    Math.Round默认采用的不是四舍五入法, 而是四舍六入的银行家算法, 如何找回四舍五入法? Math.Round默认采用的不是四舍五入法, 而是四舍六入的银行家算法,  也就是四舍六入五考虑,五 ...

  5. WPF 4 开发Windows 7 任务栏(Overlay Icon、Thumbnail Toolbar、Progress Bar)

    原文:WPF 4 开发Windows 7 任务栏(Overlay Icon.Thumbnail Toolbar.Progress Bar)      在上一篇我们介绍了如何在WPF 4 中开发Wind ...

  6. 同城快递公司Postmates近日完成1亿美元融资,美国外卖餐饮迎来一波融资热潮

    美国外卖市场尚未出现一家独大的巨头,一部分原因是与中国的外卖平台相比,在美国,外卖平台要克服的难题可能更多. 4个月之前才完成3亿美元融资的美国同城快递公司Postmates近日又完成1亿美元融资,估 ...

  7. SqlServer 使用脚本创建分发服务及事务复制的可更新订阅

    原文:SqlServer 使用脚本创建分发服务及事务复制的可更新订阅 [创建使用本地分发服务器] /************************[使用本地分发服务器配置发布]*********** ...

  8. Android零基础入门第12节:熟悉Android Studio界面,开始装逼卖萌

    原文:Android零基础入门第12节:熟悉Android Studio界面,开始装逼卖萌 通过前两期的学习,我们可以正确搭建好Android Studio的开发环境,也创建了HelloWorld工程 ...

  9. 直播的本质(创业者应该要从商业模式的右边开始思考,你为用户创造了什么价值?找客户并不难,但要想办法让客户不离不弃;PC端功能的丰富很重要,因为手机版通常只是一个迷你版)

    我想稍微给直播这件事浇点冷水. 的确,直播现在越来越火,YouTube凭着良好的基础建设平台前段时间也做起了直播,Facebook Live最近也加入了变脸.预定直播时间和双人录制的功能,更不用说国内 ...

  10. Spring的Bean的生命周期

    一:生命周期执行的过程如下:1) spring对bean进行实例化,默认bean是单例.2) spring对bean进行依赖注入.3) 如果bean实现了BeanNameAware接口,spring将 ...