题目传送门

题意简述:给出大小为 \(n\) 的字典 \(s\)。设函数 \(g(t)\) 表示 \(t\) 最多能被分割成的单词个数。等概率随机生成长度为 \(len\) 的字符串 \(T\),求 \(E(g(t))\)。

在 Luogu 博客中查看

hot tea. 比较像 P3193 [HNOI2008]GT考试

DP 大锅乱炖 & ACAM 乱做


首先对 \(s_i\) 建出 ACAM,然后在上面 DP。设 \(f_{i,j}\) 表示关于所有 \(T\)(\(|T|=i\) 且 \(T\) 在 ACAM 上能跑到状态 \(j\))的一个东西。那么究竟是表示什么呢?

记 \(P=\dfrac{f_{i,j}}{a}\);\(p\) 为 \(j\) 的所有子节点,即 \(p\in son_j\)。

错误思路:如果 \(f_{i,j}\) 单纯表示字符串 \(T\) 的 “概率”(即 \(\dfrac{num(T)}{a^i}\)),那么转移与统计答案就是:如果 \(p\) 是终止节点,将 \(ans\) 加上 \(P\);同时将所有 \(f_{i+1,p}\) 加上 \(P\)。不错,如果 \(g(T)\) 表示的是所有单词 \(s_i\) 在 \(T\) 中出现次数之和,那么这样是没错的,可惜不是,因为会有重复计算,即若字典 \(s=\{\texttt{ab,bc}\}\),那么 \(T=\{\texttt{abc}\}\) 会算入两次贡献(样例中也有提到这种情况)。

正确思路:注意到这个 "最多" 有点麻烦,不过还是有处理的办法:如果 \(p\) 是一个终止节点,那么在下传概率的时候,将 \(f_{i+1,0}\)(而不是 \(f_{i+1,p}\))加上 \(P\)。如果成功匹配一个单词,就必须从头开始匹配。

注意到 \(\sum |s_i|\) 很小,只有 \(75\)。这也意味着 \(j\) 的范围只有 \(75\)。因此,用矩阵快速幂加速 DP 即可,别忘了在矩阵中留个位置记录 \(ans\)。

总时间复杂度 \(\mathcal{O}((\sum |s_i|)^3\log len)\)。

/*
Powered by C++11.
Author : Alex_Wei.
*/ #include <bits/stdc++.h>
using namespace std; //#pragma GCC optimize(3)
//#define int long long using ld = long double; const int N=77;
const int S=26; int sz,al,son[N][S],fa[N],ed[N];
void ins(string s){
int p=0;
for(char it:s){
if(!son[p][it-'a'])son[p][it-'a']=++sz;
p=son[p][it-'a'];
} ed[p]=1;
}
void build(){
queue <int> q;
for(int i=0;i<al;i++)if(son[0][i])q.push(son[0][i]);
while(!q.empty()){
int t=q.front(); q.pop();
for(int i=0;i<al;i++)
if(son[t][i])q.push(son[t][i]),fa[son[t][i]]=son[fa[t]][i];
else son[t][i]=son[fa[t]][i];
ed[t]|=ed[fa[t]];
}
}
struct mat{
ld a[N][N];
friend mat operator * (mat x,mat y){
mat z; mem(z.a,0);
for(int i=0;i<=sz;i++)
for(int j=0;j<=sz;j++)
for(int k=0;k<=sz;k++)
z.a[i][j]+=x.a[i][k]*y.a[k][j];
return z;
}
}base,ans; int n,len;
int main(){
cin>>n>>len>>al;
for(int i=0;i<n;i++){
string s;
cin>>s,ins(s);
} build();
for(int i=0;i<=sz;i++)
for(int j=0;j<al;j++){
int p=son[i][j];
if(ed[p])base.a[i][0]+=1.0/al,base.a[i][sz+1]+=1.0/al;
else base.a[i][p]+=1.0/al;
}
sz++,ans.a[0][0]=base.a[sz][sz]=1;
while(len){
if(len&1)ans=ans*base;
base=base*base,len>>=1;
} printf("%.10Lf\n",ans.a[0][sz]);
return 0;
}

P4569 [BJWC2011]禁忌的更多相关文章

  1. 洛谷 P4569 - [BJWC2011]禁忌(AC 自动机+矩阵乘法)

    题面传送门 又好久没做过 AC 自动机的题了,做道练练手罢( 首先考虑对于某个固定的字符串怎样求出它的伤害,我们考虑贪心,每碰到出现一个模式串就将其划分为一段,最终该字符串的代价就是划分的次数.具体来 ...

  2. 题解 洛谷 P4569 【[BJWC2011]禁忌】

    考虑用\(AC\)自动机来解决本题这样的多字符串匹配问题. 要最大化魔法分割后得到的禁忌串数目,最优情况肯定为在一个串中每个禁忌串的右端点进行分割.对应到\(AC\)自动机上,就是匹配到一个禁忌串后, ...

  3. BZOJ2553 [BJWC2011]禁忌

    传送门 Description ​ 给你前alphabet个小写字母组成的字符集, 以及n个单词, 定义一个串s的禁忌值为 \(\sum_{i } [s[i] == Taboo[i]]\) , Tab ...

  4. BJWC2011 禁忌

    题目链接 题解 多模式匹配首先建 AC 自动机,看到 \(len \le 10^9\) 想到矩阵乘法优化. 朴素 DP 关于分割的最大值,可以贪心,只要走到一个能匹配串的点立刻返回根继续匹配就行,一定 ...

  5. [BJWC2011]禁忌 AC 自动机 概率与期望

    #include<cstdio> #include<algorithm> #include<cstring> #include<string> #inc ...

  6. DP 优化方法大杂烩 & 做题记录 I.

    标 * 的是推荐阅读的部分 / 做的题目. 1. 动态 DP(DDP)算法简介 动态动态规划. 以 P4719 为例讲一讲 ddp: 1.1. 树剖解法 如果没有修改操作,那么可以设计出 DP 方案 ...

  7. ACAM 题乱做

    之前做了不少 ACAM,不过没怎么整理起来,还是有点可惜的. 打 * 的是推荐一做的题目. I. *CF1437G Death DBMS 见 我的题解. II. *CF1202E You Are Gi ...

  8. 「刷题笔记」AC自动机

    自动AC机 Keywords Research 板子题,同luoguP3808,不过是多测. 然后多测不清空,\(MLE\)两行泪. 板子放一下 #include<bits/stdc++.h&g ...

  9. [No000052]大蒜怎么吃最美容?吃大蒜的功效及禁忌

    大蒜是最常见的香辛调味料,它被称为天然抗生素,富含大蒜素等多种营养物质和抗氧化剂,具有多种美肤美容作用. 大蒜的5种美容功效 1.除皱.大蒜里的某些成分,有类似维生素E与维生素C的抗氧化.防衰老特性, ...

随机推荐

  1. 巧用 CSS3 filter(滤镜) 属性

    原文链接:CSS3 filter(滤镜) 属性 效果预览 filter: grayscale(100%); 定义和使用 filter 属性定义了元素(通常是<img>)的可视效果(例如:模 ...

  2. SharkCTF2021 pwn“初见”1

    (无内鬼 今日不想学了 水一篇) nc nc nc easyoverflow Intoverflow

  3. 让全链路压测变得更简单!Takin2.0重磅来袭!

    自Takin社区版1.0发布两个多月以来,有很多测试同学陆续在各自的工作中运用了起来,其中包括金融.电商.物流.出行服务等行业.这个过程中我们收到了很多同学的反馈建议,同时也了解到很多同学在落地全链路 ...

  4. 从浏览器发送请求给SpringBoot后端时,是如何准确找到哪个接口的?(下篇)

    纸上得来终觉浅,绝知此事要躬行 注意: 本文 SpringBoot 版本为 2.5.2; JDK 版本 为 jdk 11. 前言: 前文:你了解SpringBoot启动时API相关信息是用什么数据结构 ...

  5. UltraSoft - Alpha - Postmortem 事后分析

    Alpha阶段 Postmortem会议 设想和目标 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? 主要是解决DDL提醒功能的问题,定义的比较清楚,对典型用户和典 ...

  6. 【技术博客】在Unity3d中实现烟花效果

    在游戏开发中,我们经常需要用到类似烟花的效果.在Unity3d中,实现烟花效果的方法不止一种,我选用了Unity3d中新添加的粒子特效工具--visual effect graph来进行实现. 实现过 ...

  7. 转载: VIVADO的增量综合流程

    http://xilinx.eetrend.com/content/2019/100044286.html 从 Vivado 2019.1 版本开始,Vivado 综合引擎就已经可以支持增量流程了.这 ...

  8. 新手使用python以及pycharm看过来

    前言 随着互联网时代的进步,人类与计算机之前的沟通交流越来越便捷,自此交流的媒介--编程语言吸引力更多的人学习,今天我们就来谈谈当前市面上最火的编程语言 1.文件的概念 什么是文件夹.文件 其实是操作 ...

  9. TTMS 一个基于Java Swing的Socket通信的剧院票务管理系统

    TTMS (Theater Ticket Management System) 点我进入github TTMS全称剧院票务管理系统,分为客户端和服务器端.服务器端可以接收客户端连接请求,客户端相当于我 ...

  10. 无法复现的“慢”SQL《死磕MySQL系列 八》

    系列文章 四.S 锁与 X 锁的爱恨情仇<死磕MySQL系列 四> 五.如何选择普通索引和唯一索引<死磕MySQL系列 五> 六.五分钟,让你明白MySQL是怎么选择索引< ...