POJ2778 DNA Sequence AC自动机+DP+矩阵快速幂
来源:互联网 发布:淘宝直通车常见问题 编辑:程序博客网 时间:2024/06/07 14:36
Problem Address:http://poj.org/problem?id=2778
【前言】
这道题算是出自Trie主题的。
算是一道比较综合的题目。
【思路】
(1)首先用所给的字符串构造出一个AC自动机。
这一步很简单的,也不多说了。
注意自动机的fail以及标记,如果子串为非法,则该串需标记为非法。
(2)用AC自动机构造一个DP矩阵。
该矩阵表示到达某个状态的合法转移次数。
(3)求出矩阵的n次幂,第一行的合法结点之和即为答案。
简单地矩阵快速幂。相当于普通的二分快速幂。
【代码】
#include <iostream>#include <cstring>using namespace std;char map[1005][1005];char word[1005];const int kind = 4;const int mod = 100000;const int size = 110;__int64 g[size][size];struct node{node *fail;node *next[kind];int end;int index;}trie[size];int total;node *root;node *q[size];int head, tail;inline node* new_node(){node *p = &trie[total];p->index = total;total++;p->fail = NULL;p->end = 0;memset(p->next, 0, sizeof(p->next));return p;}inline int code(char c){switch (c){case 'A': return 0;case 'T': return 1;case 'C': return 2;case 'G': return 3;}return -1;}void insert(node *root, char *s){node *p = root;int i=0, t;while(s[i]!='\0'){t = code(s[i]);if (p->next[t]==NULL)p->next[t] = new_node();p = p->next[t];i++;}p->end++;}void build_ac_automation(node *root){int i;node *temp;root->fail = NULL;head = 1;tail = 0;q[0] = root;while(head!=tail){temp = q[tail];tail++;for (i=0; i<kind; i++){if (temp->next[i]!=NULL){if (temp==root){temp->next[i]->fail = root;}else{temp->next[i]->fail = temp->fail->next[i];if (temp->next[i]->fail->end!=0)temp->next[i]->end++;}q[head] = temp->next[i];head++;}else{if (temp==root)temp->next[i] = root;elsetemp->next[i] = temp->fail->next[i];}}}}void MatrixMultiply(__int64 b[][size], __int64 c[][size], int sz){int i,j,k;__int64 temp[size][size] = {0};for (i=0; i<sz; i++){for (j=0; j<sz; j++){for (k=0; k<sz; k++){temp[i][j] += b[i][k]*c[k][j];if (temp[i][j]>=mod)temp[i][j] %= mod;}}}for (i=0; i<sz; i++){for (j=0; j<sz; j++){b[i][j] = temp[i][j];}}}void MatrixPow(__int64 t[][size], __int64 a[][size], int sz, int n){while(n>0){if (n&1) MatrixMultiply(t, a, sz);MatrixMultiply(a, a, sz);n >>= 1;}}int main(){int m,n;char word[15];int i,j;__int64 tot[size][size] = {0};__int64 ans;scanf("%d %d", &m, &n);total = 0;root = new_node();for (i=0; i<m; i++){scanf("%s", word);insert(root, word);}build_ac_automation(root);//构造AC自动机memset(g, 0, sizeof(g));for (i=0; i<total; i++)//构造DP转移矩阵{if (trie[i].end==0){for (j=0; j<kind; j++){if (trie[i].next[j]->end==0){g[i][trie[i].next[j]->index]++;}}}}memset(tot, 0, sizeof(tot));for (i=0; i<total; i++)//初始化为单位矩阵tot[i][i] = 1;MatrixPow(tot, g, total, n);//快速幂ans = 0;for (i=0; i<total; i++){if (trie[i].end==0){ans += tot[0][i];if (ans>=mod)ans %= mod;}}printf("%I64d\n", ans);return 0;}
【P.S】
最近在做POJ的contest。
只可惜功力不足,结局惨不忍睹。
然后跟别人聊了一些话,又想了很多。
于是开始糊涂起来。
不过这个暑假还是要好好努力下去,尽管和别人的差距是如此之大。
总之,不顾一切。
- POJ2778 DNA Sequence AC自动机+DP+矩阵快速幂
- poj2778 DNA Sequence AC自动机+矩阵快速幂
- poj2778 DNA Sequence(AC自动机+矩阵快速幂 )
- poj2778 DNA Sequence(AC自动机+矩阵快速幂)
- AC自动机+快速矩阵幂 poj2778 DNA Sequence
- poj2778 DNA Sequence(AC自动机+矩阵快速幂)
- 【POJ2778】 DNA Sequence AC自动机+矩阵快速幂
- POJ2778 DNA Sequence 题解(AC自动机+矩阵快速幂)
- POJ2778 DNA Sequence AC自动机+矩阵快速幂
- 【AC自动机+矩阵快速幂】poj2778 DNA Sequence
- POJ2778 DNA Sequence(AC自动机+矩阵快速幂)
- POJ2778 DNA Sequence (AC自动机+矩阵快速幂)
- POJ2778 DNA Sequence AC自动机+快速幂+DP
- POJ2778 DNA Sequence AC自动机,DP,矩阵加速
- poj2778 DNA Sequence AC自动机 dp 矩阵乘法
- poj2778--DNA Sequence(AC自动机+矩阵优化)
- POJ2778---DNA Sequence(AC自动机+矩阵)
- poj2778 DNA Sequence AC自动机+矩阵乘法
- Android 使用FTP上传文件
- Lua中 Pairs和ipairs的区别
- 判断日期合法性
- [usaco] Number Triangles
- ssh 超时设置
- POJ2778 DNA Sequence AC自动机+DP+矩阵快速幂
- S-Nim Sprague-Grundy Therem
- 一个高效的二进制数据补丁算法2009-07-19 21:09
- CSS打造分页式样
- LP_SOLVE: Linear Programming Code
- Linux中locale 详解
- Silverlight 的基本介绍
- C#是唯一能挑战Java的编程语言?
- CCS4(Code Composer Studio)的基本使用教程