poj 2778 DNA Sequence
2013-08-09 12:08
337 查看
和poj 1625一样,不同的是长度变长了
先考虑另外一个问题,给你一个有向图,从某个点出发走n步到其他任意点,问不同的走法。
对这个问题构造一个矩阵,matrix[i][j]表示从i到j有几条边,然后这个矩阵自乘n次就是答案。
再说这个问题, Trie图本身就是一个有向图,那么一个长度为n的字符串相当于从根节点沿着边走n步。。。所以和上面那个问题一样。。构造矩阵的时候要注意边不能有非法节点。
可以在构造矩阵时去掉非法节点的行和列来优化。。(这里我没去掉。。。
先考虑另外一个问题,给你一个有向图,从某个点出发走n步到其他任意点,问不同的走法。
对这个问题构造一个矩阵,matrix[i][j]表示从i到j有几条边,然后这个矩阵自乘n次就是答案。
再说这个问题, Trie图本身就是一个有向图,那么一个长度为n的字符串相当于从根节点沿着边走n步。。。所以和上面那个问题一样。。构造矩阵的时候要注意边不能有非法节点。
可以在构造矩阵时去掉非法节点的行和列来优化。。(这里我没去掉。。。
#include<cstdio> #include<cstring> #include<queue> #include<algorithm> using namespace std; typedef long long ll; const int N = 110; const int mod = (int)1e5; int top; struct Matrix{ ll d ; Matrix(int r = 0){ memset(d,0,sizeof(d)); if(r){ for(int i = 0;i < top;i++) d[i][i] = 1; } } Matrix operator *(const Matrix &a){ Matrix ans; for(int k = 0;k < top;k++) for(int i = 0;i < top;i++) for(int j = 0;j < top;j++) ans.d[i][j] = (ans.d[i][j] + d[i][k] * a.d[k][j]) % mod; return ans; } }; struct node{ node *ch[4],*fail; bool flag; void clear(){ for(int i = 0;i < 4;i++)ch[i] = NULL;fail = NULL; flag = 0; } }; int hash[129]; node stk[N*N]; struct Trie{ node *root; node* newnode(){ node *p = &stk[top++]; p -> clear(); return p; } void init(){ top = 0; root = newnode(); } void insert(char *s){ node *p = root;int len = strlen(s); for(int i = 0; i < len ;i++){ int id = hash[s[i]]; if(p -> ch[id] == NULL) p -> ch[id] = newnode(); p = p -> ch[id]; } p -> flag = 1; } void build(){ queue<node*> Q; root -> fail = root; for(int i = 0; i < 4;i++) if(root -> ch[i] == NULL) root -> ch[i] = root; else{ Q.push(root -> ch[i]); root -> ch[i] -> fail = root; } while(!Q.empty()){ node *p = Q.front();Q.pop(); for(int i = 0;i < 4;i++) if(p -> ch[i] == NULL) p -> ch[i] = p -> fail -> ch[i]; else{ Q.push(p -> ch[i]); p -> ch[i] -> fail = p -> fail -> ch[i]; p -> ch[i] -> flag |= p -> ch[i] -> fail -> flag; } } } Matrix getMatrix(){ Matrix ans; for(int i = 0;i < top;i++){ node *cur = &stk[i]; if(cur -> flag)continue; for(int j = 0;j < 4;j++){ node *next = cur -> ch[j]; if(next -> flag)continue; ans.d[i][next - stk]++; } } return ans; } }; Matrix Pow(Matrix E,int n){ Matrix ans(1); while(n){ if(n&1)ans = ans * E; E = E * E; n >>= 1; } return ans; } Trie AC; int main(){ hash['A'] = 0;hash['C'] = 1;hash['G'] = 2;hash['T'] = 3; int m,n; while(~scanf("%d%d",&m,&n)){ AC.init(); for(int i = 1;i <= m;i++){ char s[20]; scanf("%s",s); AC.insert(s); } AC.build(); Matrix E = AC.getMatrix(); Matrix ans = Pow(E,n); int number = 0; for(int i = 0;i < top;i++){ number += ans.d[0][i]; number %= mod; } printf("%d\n",number); } return 0; }
相关文章推荐
- POJ 2778 DNA Sequence [AC自动机 矩阵乘法]
- POJ 2778 DNA Sequence(AC自动机+矩阵幂DP)
- poj 2778 DNA Sequence
- POJ 2778 DNA Sequence(AC自动机+矩阵加速)
- poj 2778 AC自动机+快速幂(DNA Sequence)
- POJ 2778 DNA Sequence && AC自动机 矩阵 矩阵加速
- POJ 2778 DNA Sequence(AC自动机+矩阵加速)
- POJ 2778 DNA Sequence
- POJ 2778 DNA Sequence(AC自动机+矩阵快速幂)
- poj2778.DNA Sequence (Trie图 && 矩阵乘)
- POJ 2778 DNA Sequence(AC自动机+矩阵幂DP)
- POJ 2778 DNA Sequence(AC自动机+DP)
- POJ 2778 DNA Sequence 题解&代码
- POJ 2778 DNA Sequence (AC自动机+矩阵幂DP)
- POJ 2778 DNA Sequence (AC 自动机+矩阵)
- [POJ 2778] DNA Sequence (AC自动机+trie图+矩阵快速幂)
- POJ 2778 DNA Sequence(自动机+矩阵DP)
- poj 2778 DNA Sequence 【AC自动机 + 矩阵加速】
- POJ 2778 DNA Sequence(自动机+矩阵)
- poj 2778:DNA Sequence