【题解】Luogu P4569 [BJWC2011] 禁忌

考虑如果暴力 DP,设 \(f_{i,j}\) 为当前的串长为 \(i\),在 AC 自动机的 \(j\) 节点的概率。转移时枚举在后面加的字符 \(k\),如果加上 \(k\) 后匹配上了一个禁忌串就直接回到根节点,同时给答案贡献,否则就继续匹配。\(len\)\(10^9\),时间复杂度会超标,于是矩阵加速。

如果 \(j\) 节点可以贡献给 \(k\) 节点,那就将转移矩阵第 \(j\) 行第 \(k\) 列加上一个 \(\frac{1}{alphabet}\)。多开一行存答案,在需要累计答案时将贡献加给答案。

时间复杂度 \(O((\sum|T_i|)^3\log len)\)

#include<bits/stdc++.h>
#define ll long long
#define il inline

using namespace std;
namespace asbt{
namespace cplx{bool begin;}
int n,m,tr[80][30];
int tot,fail[80];
double ab;
bool end[80];
string s;
queue<int> q;
struct juz{
	double mat[80][80];
	juz(){
		for(int i=0;i<=tot;i++){
			for(int j=0;j<=tot;j++){
				mat[i][j]=0;
			}
		}
	}
	il double*operator[](int x){
		return mat[x];
	}
	il juz operator*(juz x)const{
		juz res;
		for(int i=0;i<=tot;i++){
			for(int j=0;j<=tot;j++){
				for(int k=0;k<=tot;k++){
					res[i][j]+=mat[i][k]*x[k][j];
				}
			}
		}
		return res;
	}
}bas;
il juz qpow(juz x,int y){
	juz res;
	for(int i=0;i<=tot;i++){
		res[i][i]=1;
	}
	while(y){
		if(y&1){
			res=res*x;
		}
		y>>=1,x=x*x;
	}
	return res;
}
namespace cplx{
	bool end;
	il double usdmem(){return (&begin-&end)/1048576.0;}
}
int main(){
	ios::sync_with_stdio(0),cin.tie(0);
	cin>>n>>m>>ab;
	for(int i=1,p;i<=n;i++){
		cin>>s;
		p=0;
		for(int j=0,d;j<s.size();j++){
			d=s[j]-'a';
			if(!tr[p][d]){
				tr[p][d]=++tot;
			}
			p=tr[p][d];
		}
		end[p]=1;
	}
	for(int i=0;i<ab;i++){
		if(tr[0][i]){
			q.push(tr[0][i]);
		}
	}
	while(q.size()){
		int u=q.front();
		q.pop();
		for(int i=0;i<ab;i++){
			if(tr[u][i]){
				fail[tr[u][i]]=tr[fail[u]][i];
				end[tr[u][i]]|=end[fail[tr[u][i]]];
				q.push(tr[u][i]);
			}
			else{
				tr[u][i]=tr[fail[u]][i];
			}
		}
	}
//	for(int i=0;i<=tot;i++){
//		cout<<fail[i]<<" ";
//	}
//	puts("");
	tot++;
	for(int i=0;i<tot;i++){
		for(int j=0;j<ab;j++){
			if(end[tr[i][j]]){
				bas[i][0]+=1.0/ab;
				bas[i][tot]+=1.0/ab;
			}
			else{
				bas[i][tr[i][j]]+=1.0/ab;
			}
		}
	}
	bas[tot][tot]=1;
	printf("%.10f",qpow(bas,m)[0][tot]);
	return 0;
}
}
int main(){return asbt::main();}
posted @ 2025-02-06 20:11  zhangxy__hp  阅读(32)  评论(0)    收藏  举报