POJ - 2778

Posted chasedeath

tags:

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

POJ - 2778

对于所有串构建AC自动机,将AC自动机上的位置作为状态,暴力矩阵转移即可



int n,m;
int a[N];
char s[N];
int val[N];

const int SIZE=101;
int trie[SIZE][4];
int End[SIZE];
int fail[SIZE],cnt;

int ch[N];
int Insert(char *s){ 
	int p=0;
	int l=0;
	while(s[l]!=‘‘) l++;
	rep(i,0,l-1) {
		int x=ch[(int)s[i]];
		if(!trie[p][x]) trie[p][x]=++cnt;
		p=trie[p][x];
	}
	return p;
}

void Build() {
	static queue <int> que;
	rep(i,0,3) if(trie[0][i]) que.push(trie[0][i]);
	while(!que.empty()) {
		int u=que.front(); que.pop();
		End[u]|=End[fail[u]];
		rep(i,0,3) {
			int &v=trie[u][i];
			if(v) {
				que.push(v);
				fail[v]=trie[fail[u]][i];
			} else v=trie[fail[u]][i];
		}
	}
}

struct Mat{
	int a[SIZE][SIZE];
	void init(){ memset(a,0,sizeof a); }
	void Get1(){ rep(i,0,cnt) a[i][i]=1; }
	Mat operator * (const Mat x) const{
		Mat res; res.init();
		rep(i,0,cnt) rep(j,0,cnt) rep(o,0,cnt) res.a[i][o]=(res.a[i][o]+1ll*a[i][j]*x.a[j][o])%P;
		return res;
	}
}x,res;

int f[1][SIZE],ans[1][SIZE];


int main(){
	ch[(int)‘A‘]=0,ch[(int)‘T‘]=1,ch[(int)‘C‘]=2,ch[(int)‘G‘]=3;
	m=rd(),n=rd();
	rep(i,1,m) {
		scanf("%s",s);
		End[Insert(s)]=1;
	}
	Build();
	f[0][0]=1;
	rep(i,0,cnt) if(!End[i]) {
		rep(j,0,3) {
			int nxt=trie[i][j];
			if(End[nxt]) continue;
			x.a[i][nxt]++;
		}
	}
	res.Get1();
	while(n) {
		if(n&1) res=res*x;
		x=x*x;
		n>>=1;
	}
	rep(i,0,0) rep(j,0,cnt) rep(o,0,cnt) ans[i][o]=(ans[i][o]+1ll*f[i][j]*res.a[j][o])%P;
	int Ans=0;
	rep(i,0,cnt) (Ans+=ans[0][i])%=P;
	printf("%d
",Ans);
}

以上是关于POJ - 2778的主要内容,如果未能解决你的问题,请参考以下文章

poj2778 AC自动机

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

POJ - 2778

poj 2778 AC自己主动机 + 矩阵高速幂

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

2778:Ride to School-poj