码迷,mamicode.com
首页 > 其他好文 > 详细

POJ - 2778

时间:2020-05-21 15:58:56      阅读:39      评论:0      收藏:0      [点我收藏+]

标签:ati   front   转移   return   class   printf   pre   problem   pop   

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]!=‘\0‘) 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\n",Ans);
}

POJ - 2778

标签:ati   front   转移   return   class   printf   pre   problem   pop   

原文地址:https://www.cnblogs.com/chasedeath/p/12931289.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!