DNA Sequence POJ - 2778 AC 自动机 矩阵乘法

Posted guangheli

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了DNA Sequence POJ - 2778 AC 自动机 矩阵乘法相关的知识,希望对你有一定的参考价值。

定义重载运算的时候一定要将矩阵初始化,因为这个调了一上午......

Code:

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<string>
#define maxn 100000
typedef long long ll;
using namespace std;
void setIO(string a){ freopen((a+".in").c_str(),"r",stdin); }

char arr[maxn];
int mod, nodes;
struct matrix{
    int m[105][105];
}mat;
void init(matrix &c){ for(int i=0;i<=nodes;++i) c.m[i][i]=1; } 
void get(matrix &c) {for(int i=0;i<=nodes;++i) for(int j=0;j<=nodes;++j) c.m[i][j]=0;}
void print(matrix a){
	for(int i=0;i<=nodes;++i){
		for(int j=0;j<=nodes;++j) printf("%d ",a.m[i][j]);
		printf("
");
	}
}
matrix operator*(matrix a,matrix b){
	matrix c;
	get(c);
	for(int i=0;i<=nodes;++i)
		for(int j=0;j<=nodes;++j)
			for(int k=0;k<=nodes;++k){
				c.m[i][j]+=((ll)a.m[i][k]*b.m[k][j])%mod;
				c.m[i][j]%=mod;
			}
	return c;
}
matrix power(matrix a,long long k){
    matrix ans;
    for(int i=0;i<=nodes;++i) ans.m[i][i]=1;
    while(k){
        if(k&1)ans=ans*a;
        a=a*a;
        k/=2;
    }
    return ans;
}
struct Automaton{
	#define sigma 4
	int get(char s){
		if(s==‘A‘) return 0;
		if(s==‘C‘) return 1;
		if(s==‘T‘) return 2;
		if(s==‘G‘) return 3;
	}
	int ch[maxn][sigma],tag[maxn],fail[maxn];
	void insert(char str[]){
		int n=strlen(str);
		int j=0;
		for(int i=0;i<n;++i){
			if(!ch[j][get(str[i])]) ch[j][get(str[i])]=++nodes;
			j=ch[j][get(str[i])];
		}
		tag[j]=1;
	}
	queue<int>Q;
	void build(){
		for(int i=0;i<sigma;++i) if(ch[0][i]) Q.push(ch[0][i]);
		while(!Q.empty()){
			int u=Q.front();Q.pop();
			if(tag[fail[u]]) tag[u]=1;
			for(int i=0;i<sigma;++i){
				int r=ch[u][i];
				if(!r) { ch[u][i]=ch[fail[u]][i]; continue; }
				fail[r]=ch[fail[u]][i];
				Q.push(r);
			}
		}

		for(int i=0;i<=nodes;++i)
		    for(int j=0;j<sigma;++j)
		    	if(!tag[i]&&!tag[ch[i][j]]) mat.m[i][ch[i][j]]+=1;

	}
}aho;


int main(){
	//setIO("input");
	mod=100000;
	int m, ans=0;  long long n;
	scanf("%d%lld",&m,&n);
	for(int i=1;i<=m;++i)scanf("%s",arr), aho.insert(arr);
	aho.build();
    matrix fin=power(mat,n);
    for(int i=0;i<=nodes;++i)  ans=(ans+fin.m[0][i])%mod;
    printf("%d",ans);
    return 0;
}

  

以上是关于DNA Sequence POJ - 2778 AC 自动机 矩阵乘法的主要内容,如果未能解决你的问题,请参考以下文章

POJ2778 DNA Sequence

POJ2778DNA Sequence(AC自动机)

POJ2778 DNA Sequence AC自动机上dp

线性代数(矩阵乘法):POJ 2778 DNA Sequence

POJ 2778 DNA Sequence(AC自动机+矩阵快速幂)

[POJ2778]DNA Sequence(AC自动机 + DP + 矩阵优化)