【Ac自動機+矩陣加速】poj 2778 DNA Sequence
Link:http://poj.org/problem?id=2778
字典樹的每個節點作為一個狀態,矩陣記錄i點走一步的可行的狀態轉移的方法數,用矩陣快速冪計算所有可行的方法數。
//#include <bits/stdc++.h>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
typedef long long LL;
const int mod = 100000;
const int N = 15;
const int M = 4;
const int root = 0;
//char to[5] = {"ACTG"};
int change(char c){
if(c == 'A')
return 0;
if(c == 'C')
return 1;
if(c == 'T')
return 2;
if(c == 'G')
return 3;
}
struct Ma{
LL p[N*N][N*N];
int Size;
void init(int _n){
Size = _n;
for(int i = 0; i < Size; i++)
for(int j = 0; j < Size; j++)
p[i][j] = 0;
}
};
struct Aho
{
struct Node{
int nex[M];
int fail,endd;
}node[N*N];
int Size;
queue<int> que;
int newnode(){
for(int i = 0; i < M; i++)
node[Size].nex[i] = 0;
node[Size].fail = node[Size].endd = 0;
return Size++;
}
void init(){
while(que.size()) que.pop();
Size = root;
newnode();
}
void Insert(char *s)
{
int L = strlen(s);
int now = root;
for(int i = 0; i < L; i++){
int x = change(s[i]);
if(node[now].nex[x]==0)
node[now].nex[x]=newnode();
now = node[now].nex[x];
}
node[now].endd = 1;
}
void build()
{
node[root].fail = root;
for(int i = 0; i < M; i++)
{
if(node[root].nex[i])
{
node[node[root].nex[i]].fail = root;
que.push(node[root].nex[i]);
}
}
while(que.size())
{
int u = que.front();
if(node[node[u].fail].endd) //當u的字尾是病毒,u也不能出現.
node[u].endd = 1;
que.pop();
for(int i = 0; i < M; i++)
{
if(node[u].nex[i]==0)
node[u].nex[i] = node[node[u].fail].nex[i];
else
{
node[node[u].nex[i]].fail = node[node[u].fail].nex[i];
que.push(node[u].nex[i]);
}
}
}
// for(int i = 0; i < Size; i++)
// printf("[%d %d %d]\n",i,node[i].fail,node[i].endd);
}
Ma getMa()
{
Ma mat;
mat.init(Size);
for(int i = root; i < Size; i++){
for(int j = 0; j < M; j++){
if(!node[i].endd && !node[node[i].nex[j]].endd)
mat.p[i][node[i].nex[j]] ++;
}
}
return mat;
}
}aho;
Ma Ma_mult(Ma a,Ma b)
{
Ma c;
c.init(a.Size);
for(int i = 0; i < a.Size; i++){
for(int j = 0; j < a.Size; j++){
for(int k = 0; k < a.Size; k++)
c.p[i][j] += a.p[i][k]*b.p[k][j];
c.p[i][j] %= mod;
}
}
return c;
}
Ma quick_mi(Ma a,int n)
{
Ma c;
c.init(a.Size);
for(int i = 0; i < c.Size; i++)
c.p[i][i] = 1;
while(n)
{
if(n&1) c = Ma_mult(c,a);
a = Ma_mult(a,a);
n >>= 1;
}
return c;
}
char s[N];
int main()
{
int m,n;
while(~scanf("%d %d",&m,&n))
{
aho.init();
for(int i = 0; i < m; i++)
{
scanf("%s",s);
aho.Insert(s);
}
aho.build();
Ma mat = aho.getMa();
// for(int i = 0; i < mat.Size; i++)
// {
// for(int j = 0; j < mat.Size; j++)
// printf("%lld ",mat.p[i][j]);
// puts("");
// }
mat = quick_mi(mat,n);
LL ans = 0;
for(int i = 0; i < mat.Size; i++)
ans += mat.p[0][i];
printf("%lld\n",ans%mod);
}
return 0;
}
相關文章
- poj--2778DNA Sequence+AC自動機+矩陣快速冪矩陣
- POJ 2778-DNA Sequence(AC自動機+構建鄰接矩陣+矩陣快速冪)矩陣
- poj 2778 AC自動機與矩陣連乘矩陣
- POJ 3691 DNA repair (AC自動機 + dp)AI
- hdu2243 ac自動機+矩陣連乘矩陣
- AC自動機+字典序+樹狀陣列陣列
- 巨大的矩陣(矩陣加速)矩陣
- HDU3519Lucky Coins Sequence(DP+矩陣加速)矩陣
- 動態dp & 矩陣加速遞推矩陣
- [複習] AC自動機
- AC自動機 提高篇
- 【精選】矩陣加速矩陣
- cuda 加速矩陣乘法矩陣
- POJ 3581-Sequence(字尾陣列)陣列
- HDU 1005 Number Sequence(矩陣)矩陣
- AC自動機:Tire樹+KMPKMP
- 矩陣類 poj3420矩陣
- POJ 3613 Cow Relays 矩陣乘法Floyd+矩陣快速冪矩陣
- 序列(dp+矩陣加速)矩陣
- 演算法學習:矩陣快速冪/矩陣加速演算法矩陣
- AC 自動機——多模式串匹配模式
- AC自動機學習筆記筆記
- 【Ac自動機】hdu 5880 Family ViewView
- AC 自動機學習筆記筆記
- POJ 3744 概率dp+矩陣矩陣
- 矩陣快速冪加速最短路矩陣
- 矩陣加速線性遞推矩陣
- 雜項——矩陣加速(進階)矩陣
- HDU 1005 Number Sequence(矩陣快速冪)矩陣
- HDU 1005 Number Sequence:矩陣快速冪矩陣
- poj1050 最大子矩陣和矩陣
- hdu 1277 AC自動機入門(指標版和陣列版)指標陣列
- LeetCode-Repeated DNA SequenceLeetCode
- 巨大的數(dp+矩陣加速)矩陣
- 幸運數(dp+矩陣加速)矩陣
- 從零開始發明 AC 自動機
- POJ 1050-To the Max(最大子矩陣和)矩陣
- 隨機矩陣隨機矩陣