【BZOJ 2553】[BeiJing2011]禁忌 AC自动机+期望概率dp
我一开始想的是倒着来,发现太屎,后来想到了一种神奇的方法——我们带着一个既有期望又有概率的矩阵,偶数(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=;
char s[];
int alpha,n,m;
struct Trie{
int ch[],fail,deep;
bool god;
}node[N];
int sz,q[N],size;
LD a[N][N],temp_a[N][N],b[N],temp_b[N],need;
inline void insert(char *w){
int p=;
for(int i=;w[i];i++){
if(node[p].ch[w[i]-'a']==)node[p].ch[w[i]-'a']=++sz,node[sz].deep=node[p].deep+;
p=node[p].ch[w[i]-'a'];
}
node[p].god=;
}
inline void build(){
q[]=;
for(int i=,j=;i<=j;i++){
for(int l=;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]:,
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]:;
}
}
void dfs(int x){
for(int i=;i<alpha;i++){
if(node[node[x].ch[i]].god){
a[][x<<]+=need;
a[][(x<<)+]+=need;
a[][(x<<)+]+=need;
continue;
}
a[node[x].ch[i]<<][x<<]+=need;
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=;i<=size;i++)
for(int j=;j<=size;j++)
temp_a[i][j]=;
for(int i=;i<=size;i++)
for(int j=;j<=size;j++)
for(int k=;k<=size;k++)
temp_a[i][j]+=a[i][k]*a[k][j];
for(int i=;i<=size;i++)
for(int j=;j<=size;j++)
a[i][j]=temp_a[i][j];
}
inline void Multi_b(){
for(int i=;i<=size;i++)temp_b[i]=;
for(int i=;i<=size;i++)
for(int j=;j<=size;j++)
temp_b[i]+=a[i][j]*b[j];
for(int i=;i<=size;i++)b[i]=temp_b[i];
}
int main(){
scanf("%d%d%d",&n,&m,&alpha),need=./alpha;
for(int i=;i<=n;i++)
scanf("%s",s),insert(s);
build(),dfs(),size=(sz<<)+,b[]=.;
while(m){
if(m&)Multi_b();
m>>=,Multi_a();
}
LD ans=.;
for(int i=;i<=sz;i++)ans+=b[i<<];
printf("%lf",(double)ans);
return ;
}
只是错了最后一个点
然后我去接受正解,按照我们的思路我们会建出来一个概率矩阵a[i][j]表示由j转移到i的概率,那就是加上1/alphabet,当然这里也有从禁忌串直接调回0的操作,然后我们想记录答案,我们就把矩阵扩大一阶,标号为sz+1,就是记录答案,那么我们由禁忌串向sz+1加上1/alphabet,那么我们发现这个矩阵自乘多少次,他的a[sz+1][0]的答案就是我们想要的答案。
经验教训:对于矩阵乘法,答案矩阵也可以是方阵,而且在一个矩阵里意义可以不同。
#include <cstdio>
#include <cstring>
#include <vector>
typedef long double LD;
const int N=;
char s[];
int alpha,n,m;
struct Trie{
int ch[],fail,deep;
bool god;
}node[N];
int sz,q[N],size;
LD a[N][N],temp[N][N],b[N][N],need;
inline void insert(char *w){
int p=;
for(int i=;w[i];i++){
if(node[p].ch[w[i]-'a']==)node[p].ch[w[i]-'a']=++sz,node[sz].deep=node[p].deep+;
p=node[p].ch[w[i]-'a'];
}
node[p].god=;
}
inline void build(){
q[]=;
for(int i=,j=;i<=j;i++){
for(int l=;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]:,
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]:;
}
}
void dfs(int x){
for(int i=;i<alpha;i++){
if(node[node[x].ch[i]].god){
a[][x]+=need;
a[sz+][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=;i<=size;i++)
for(int j=;j<=size;j++)
temp[i][j]=;
for(int i=;i<=size;i++)
for(int j=;j<=size;j++)
for(int k=;k<=size;k++)
temp[i][j]+=a[i][k]*a[k][j];
for(int i=;i<=size;i++)
for(int j=;j<=size;j++)
a[i][j]=temp[i][j];
}
inline void Multi_b(){
for(int i=;i<=size;i++)
for(int j=;j<=size;j++)
temp[i][j]=;
for(int i=;i<=size;i++)
for(int j=;j<=size;j++)
for(int k=;k<=size;k++)
temp[i][j]+=b[i][k]*a[k][j];
for(int i=;i<=size;i++)
for(int j=;j<=size;j++)
b[i][j]=temp[i][j];
}
int main(){
scanf("%d%d%d",&n,&m,&alpha),need=(LD)./(LD)alpha;
for(int i=;i<=n;i++)
scanf("%s",s),insert(s);
build(),dfs(),size=sz+,a[size][size]=.;
for(int i=;i<=size;i++)b[i][i]=.;
while(m){
if(m&)Multi_b();
m>>=,Multi_a();
}
printf("%.6lf",(double)b[size][]);
return ;
}
AC code
【BZOJ 2553】[BeiJing2011]禁忌 AC自动机+期望概率dp的更多相关文章
- 【BZOJ】2553: [BeiJing2011]禁忌 AC自动机+期望+矩阵快速幂
[题意]给定n个禁忌字符串和字符集大小alphabet,保证所有字符在集合内.一个字符串的禁忌伤害定义为分割能匹配到最多的禁忌字符串数量(一个可以匹配多次),求由字符集构成的长度为Len的字符串的期望 ...
- bzoj 2553: [BeiJing2011]禁忌 AC自动机+矩阵乘法
题目大意: http://www.lydsy.com/JudgeOnline/problem.php?id=2553 题解: 利用AC自动机的dp求出所有的转移 然后将所有的转移储存到矩阵中,进行矩阵 ...
- bzoj 2553 [BeiJing2011]禁忌——AC自动机+概率DP+矩阵
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2553 看了题解才会…… 首先,给定一个串,最好的划分方式是按禁忌串出现的右端点排序,遇到能填 ...
- 【BZOJ2553】[BeiJing2011]禁忌 AC自动机+期望DP+矩阵乘法
[BZOJ2553][BeiJing2011]禁忌 Description Magic Land上的人们总是提起那个传说:他们的祖先John在那个东方岛屿帮助Koishi与其姐姐Satori最终战平. ...
- 【BZOJ 3811】玛里苟斯 大力观察+期望概率dp+线性基
大力观察:I.从输出精准位数的约束来观察,一定会有猫腻,然后仔细想一想,就会发现输出的时候小数点后面不是.5就是没有 II.从最后答案小于2^63可以看出当k大于等于3的时候就可以直接搜索了 期望概率 ...
- BZOJ2553[BeiJing2011]禁忌——AC自动机+概率DP+矩阵乘法
题目描述 Magic Land上的人们总是提起那个传说:他们的祖先John在那个东方岛屿帮助Koishi与其姐姐Satori最终战平.而后,Koishi恢复了读心的能力…… 如今,在John已经成为传 ...
- BZOJ2553 [BeiJing2011]禁忌 AC自动机 矩阵
原文链接http://www.cnblogs.com/zhouzhendong/p/8196279.html 题目传送门 - BZOJ2553 题意概括 引用一下lych大佬的: 在字母只有前alph ...
- BZOJ 1559: [JSOI2009]密码( AC自动机 + 状压dp )
建AC自动机后, dp(x, y, s)表示当前长度为x, 在结点y, 包括的串的状态为s的方案数, 转移就在自动机上走就行了. 对于输出方案, 必定是由给出的串组成(因为<=42), 所以直接 ...
- BZOJ 3270 博物馆 && CodeForces 113D. Museum 期望概率dp 高斯消元
大前提,把两个点的组合看成一种状态 x 两种思路 O(n^7) f[x]表示在某一个点的前提下,这个状态经过那个点的概率,用相邻的点转移状态,高斯一波就好了 O(n^6) 想象成臭气弹,这个和那个的区 ...
随机推荐
- Scala语法(二)
(1)类,对象 //定义类(属性.方法),实例化对象 class counter{ *//主构造器 class counter(name:String,mode:Int){ ... } 实例化:val ...
- web学习第一天
学习web心得 表格 table,表单 form,跑马灯效果 marquee,导入背景图片<img src="图片路径"> 第一天学的不是很难,作业也相对来说比较简单, ...
- Java学习笔记七:Java的流程控制语句之switch
Java条件语句之 switch 当需要对选项进行等值判断时,使用 switch 语句更加简洁明了.例如:根据考试分数,给予前四名不同的奖品.第一名,奖励笔记本一台:第二名,奖励 IPAD 2 一个: ...
- go学习笔记-程序测试
程序测试 测试是一个可重复的过程,它验证某个东西是否按预期工作.一般通过 go test 进行测试,步骤如下 首先,是我们的文件名.Go 要求所有的测试都在以 _test.go 结尾的文件中.这使得我 ...
- Java8新特性(三)——Optional类、接口方法与新时间日期API
一.Optional容器类 这是一个可以为null的容器对象.如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象. 查看结构图可以看到有如下常用方法: of(T)—— ...
- 【转】Ubuntu 14.04下Django+MySQL安装部署全过程
一.简要步骤.(阿里云Ubuntu14.04) Python安装 Django Mysql的安装与配置 记录一下我的部署过程,也方便一些有需要的童鞋,大神勿喷~ 二.Python的安装 由于博主使用的 ...
- 浅析 Linux 初始化 init 系统,Systemd
原文地址:http://www.ibm.com/developerworks/cn/linux/1407_liuming_init3/ Systemd 的简介和特点 Systemd 是 Linux 系 ...
- PS作业
- MySQL数据库性能优化专题
摘录: 书:<MySQL性能调优与架构设计> 一个系列: (按顺序排一下) MySQL 数据库性能优化之缓存参数优化 http://isky000.com/database/mysql-p ...
- vux用法
其实官网写的很详细了 但是好多时候没有仔细看的耐心 下面基本也是vux官网步骤: 很多人需要$t未定义问题 其实按着官网来就能解决这个报错: 如果你遇到 $t 报错问题,请不要开 issue,升级 v ...