您的位置:首页 > 产品设计 > UI/UE

poj 2778 DNA Sequence

2013-08-09 12:08 337 查看
  和poj 1625一样,不同的是长度变长了

  先考虑另外一个问题,给你一个有向图,从某个点出发走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;
}


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: