您的位置:首页 > 其它

【BZOJ 2553】[BeiJing2011]禁忌 AC自动机+期望概率dp

2017-09-15 21:40 435 查看
我一开始想的是倒着来,发现太屎,后来想到了一种神奇的方法——我们带着一个既有期望又有概率的矩阵,偶数(2*id)代表期望,奇数(2*id+1)代表概率,初始答案矩阵一列,1的位置为1(起点为0),工具矩阵上如果是直接转移那么就是由i到j概率期望都乘上1/alphabet,特别的,对于一个包含禁忌串的节点直接由其父节点指向0,而且在计算期望是多加上他的概率,最后统计答案时把答案矩阵上所有的期望加和即可,这个方法很完美的被卡精了.......

#include <cstdio>
#include <cstring>
#include <vector>
typedef long double LD;
const int N=100;
char s[20];
int alpha,n,m;
struct Trie{
int ch[26],fail,deep;
bool god;
}node
;
int sz,q
,size;
LD a

,temp

,b

,need;
inline void insert(char *w){
int p=0;
for(int i=0;w[i];i++){
if(node[p].ch[w[i]-'a']==0)node[p].ch[w[i]-'a']=++sz,node[sz].deep=node[p].deep+1;
p=node[p].ch[w[i]-'a'];
}
node[p].god=1;
}
inline void build(){
q[0]=0;
for(int i=0,j=0;i<=j;i++){
for(int l=0;l<alpha;l++)
if(node[q[i]].ch[l])
q[++j]=node[q[i]].ch[l],
node[q[j]].fail=q[i]?node[node[q[i]].fail].ch[l]:0,
node[q[j]].god=node[q[j]].god||node[node[q[j]].fail].god;
else
node[q[i]].ch[l]=q[i]?node[node[q[i]].fail].ch[l]:0;
}
}
void dfs(int x){
for(int i=0;i<alpha;i++){
if(node[node[x].ch[i]].god){
a[0][x]+=need;
a[sz+1][x]+=need;
continue;
}
a[node[x].ch[i]][x]+=need;
if(node[node[x].ch[i]].deep>node[x].deep)
dfs(node[x].ch[i]);
}
}
inline void Multi_a(){
for(int i=0;i<=size;i++)
for(int j=0;j<=size;j++)
temp[i][j]=0;
for(int i=0;i<=size;i++)
for(int j=0;j<=size;j++)
for(int k=0;k<=size;k++)
temp[i][j]+=a[i][k]*a[k][j];
for(int i=0;i<=size;i++)
for(int j=0;j<=size;j++)
a[i][j]=temp[i][j];
}
inline void Multi_b(){
for(int i=0;i<=size;i++)
for(int j=0;j<=size;j++)
temp[i][j]=0;
for(int i=0;i<=size;i++)
for(int j=0;j<=size;j++)
for(int k=0;k<=size;k++)
temp[i][j]+=b[i][k]*a[k][j];
for(int i=0;i<=size;i++)
for(int j=0;j<=size;j++)
b[i][j]=temp[i][j];
}
int main(){
scanf("%d%d%d",&n,&m,&alpha),need=(LD)1./(LD)alpha;
for(int i=1;i<=n;i++)
scanf("%s",s),insert(s);
build(),dfs(0),size=sz+1,a[size][size]=1.;
for(int i=0;i<=size;i++)b[i][i]=1.;
while(m){
if(m&1)Multi_b();
m>>=1,Multi_a();
}
printf("%.6lf",(double)b[size][0]);
return 0;
}


AC code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: