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的主要内容,如果未能解决你的问题,请参考以下文章
POJ 2778 DNA Sequence(AC自动机+矩阵)