[BJWC2011]禁忌 AC 自动机 概率与期望
#include<cstdio> #include<algorithm> #include<cstring> #include<string> #include<queue> #include<cstdlib> #include<iostream> using namespace std; void setIO(string a){ freopen((a+".in").c_str(),"r",stdin); } #define db long double #define maxn 100000 char arr[maxn]; int sigma, nodes, n; struct matrix{ long double mat[150][150]; }unit; void init(matrix &a){ for(int i=0;i<=n;++i) for(int j=0;j<=n;++j) a.mat[i][j]=0; } void get(matrix &a){ init(a); for(int i=0;i<=n;++i) a.mat[i][i]=1; } matrix operator*(matrix a,matrix b){ matrix c; init(c); for(int i=0;i<=n;++i) for(int j=0;j<=n;++j) for(int k=0;k<=n;++k) c.mat[i][j]+=a.mat[i][k]*b.mat[k][j]; return c; } matrix operator^(matrix a,int p){ matrix ans; get(ans); while(p){ if(p&1) ans=ans*a; a=a*a; p>>=1; } return ans; } struct Automaton{ int ch[maxn][30], fail[maxn], tag[maxn]; #define idx str[i]-'a' void insert(char str[]){ int cnt=strlen(str),j=0; for(int i=0;i<cnt;++i) { if(!ch[j][idx]) ch[j][idx]=++nodes; j=ch[j][idx]; } tag[j]=true, n=nodes+1; } queue<int>Q; bool vis[maxn]; 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(); for(int i=0;i<sigma;++i){ int r=ch[u][i]; if(!r){ ch[u][i]=ch[fail[u]][i]; continue;} Q.push(r), fail[r]=ch[fail[u]][i], tag[r]|=tag[fail[r]]; } } init(unit); Q.push(0), vis[0]=true; long double tmp=(long double)1/sigma; while(!Q.empty()){ int u=Q.front();Q.pop(); for(int i=0;i<sigma;++i){ if(!vis[ch[u][i]]) vis[ch[u][i]]=true, Q.push(ch[u][i]); if(tag[ch[u][i]]) unit.mat[u][0]+=tmp, unit.mat[u][n]+=tmp; else unit.mat[u][ch[u][i]]+=tmp; } unit.mat[n][n]=1; } } }aho; int main(){ //setIO("input"); int m,len; scanf("%d%d%d",&m,&len,&sigma); for(int i=1;i<=m;++i) scanf("%s",arr), aho.insert(arr); aho.build(); matrix g=unit^len; printf("%.10f",(double)g.mat[0][n]); return 0; }
说实话还是有点不太理解.....
Code: