BZOJ2553 [BeiJing2011]禁忌 AC自动机 矩阵
原文链接http://www.cnblogs.com/zhouzhendong/p/8196279.html
题目传送门 - BZOJ2553
题意概括
引用一下lych大佬的:
在字母只有前alphabet时,给定N个串,求长度为len的串包含这些N个串的个数最大值的期望值。
题解
我们首先发现总共的字符个数才就75个,那么闭着眼睛先建一个AC自动机,Trie图建好。反正代码不长。
然后我们发现长度很大,显然就是要往矩阵快速幂那里考虑。
我们可以用矩阵来快速计算到达AC自动机的每一个位置的概率。
然后我们考虑原问。
对于一个串,把它划分成包含最多的禁忌串数的方案怎么做?
我们可以贪心的来,从头开始沿着字符串在AC自动机上面走,每一次到一个结束点就划分。这样一定是最优的。
然后回到矩阵中。
假如说我们考虑DP的话,那么每到一个结束点,都要统计一下当前概率对答案的贡献,就是概率*1
那么我们可以把它记入答案中。
同理,我们可以在矩阵中多开一列,用来维护答案。
代码
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <cmath>
using namespace std;
typedef long double LD;
const int S=80;
struct Trie{
int fail,e,Next[26];
void clear(){
fail=e=0;
memset(Next,0,sizeof Next);
}
}tree[S];
int n,len,alpha,cnt;
void build(char ch[]){
int rt=1,t,len=strlen(ch);
for (int i=0;i<len;i++){
t=ch[i]-'a';
if (!tree[rt].Next[t]){
tree[++cnt].clear();
tree[rt].Next[t]=cnt;
}
rt=tree[rt].Next[t];
}
tree[rt].e=1;
}
void build_AC(){
int q[S],head=0,tail=0;
int rt,son,k;
q[++tail]=1,tree[0].fail=1;
while (head<tail){
int rt=q[++head];
for (int i=0;i<alpha;i++){
son=tree[rt].Next[i];
if (!son){
tree[rt].Next[i]=tree[tree[rt].fail].Next[i];
continue;
}
k=tree[rt].fail;
while (!tree[k].Next[i])
k=tree[k].fail;
tree[son].fail=tree[k].Next[i];
tree[son].e|=tree[tree[k].Next[i]].e;
q[++tail]=son;
}
}
}
int m;
struct Mat{
LD v[S][S];
Mat (){}
Mat (int x){set(x);}
void print(){
for (int i=1;i<=m;i++,puts(""))
for (int j=1;j<=m;j++)
printf("%5.3Lf ",v[i][j]);
puts("");
}
void set(int x){
memset(v,0,sizeof v);
if (x==1)
for (int i=1;i<=m;i++)
v[i][i]=1;
}
Mat operator * (Mat b){
Mat ans(0);
for (int i=1;i<=m;i++)
for (int j=1;j<=m;j++)
for (int k=1;k<=m;k++)
ans.v[i][j]+=v[i][k]*b.v[k][j];
return ans;
}
Mat operator ^ (int y){
Mat ans(1),x=*this;
while (y){
if (y&1)
ans=ans*x;
x=x*x;
y>>=1;
}
return ans;
}
}M(0);
char s[S];
int main(){
scanf("%d%d%d",&n,&len,&alpha);
cnt=1;
tree[0].clear();
tree[1].clear();
for (int i=0;i<alpha;i++)
tree[0].Next[i]=1;
for (int i=1;i<=n;i++){
scanf("%s",s);
build(s);
}
build_AC();
m=cnt+1;
LD addv=1.0/(1.0*alpha);
for (int i=1;i<=cnt;i++)
for (int j=0;j<alpha;j++)
if (tree[tree[i].Next[j]].e)
M.v[i][1]+=addv,M.v[i][m]+=addv;
else
M.v[i][tree[i].Next[j]]+=addv;
M.v[m][m]=1;
Mat Mans=M^len;
printf("%.10lf",(double)Mans.v[1][m]);
return 0;
}
BZOJ2553 [BeiJing2011]禁忌 AC自动机 矩阵的更多相关文章
- BZOJ2553[BeiJing2011]禁忌——AC自动机+概率DP+矩阵乘法
题目描述 Magic Land上的人们总是提起那个传说:他们的祖先John在那个东方岛屿帮助Koishi与其姐姐Satori最终战平.而后,Koishi恢复了读心的能力…… 如今,在John已经成为传 ...
- bzoj 2553: [BeiJing2011]禁忌 AC自动机+矩阵乘法
题目大意: http://www.lydsy.com/JudgeOnline/problem.php?id=2553 题解: 利用AC自动机的dp求出所有的转移 然后将所有的转移储存到矩阵中,进行矩阵 ...
- 【BZOJ】2553: [BeiJing2011]禁忌 AC自动机+期望+矩阵快速幂
[题意]给定n个禁忌字符串和字符集大小alphabet,保证所有字符在集合内.一个字符串的禁忌伤害定义为分割能匹配到最多的禁忌字符串数量(一个可以匹配多次),求由字符集构成的长度为Len的字符串的期望 ...
- 【BZOJ2553】[BeiJing2011]禁忌 AC自动机+期望DP+矩阵乘法
[BZOJ2553][BeiJing2011]禁忌 Description Magic Land上的人们总是提起那个传说:他们的祖先John在那个东方岛屿帮助Koishi与其姐姐Satori最终战平. ...
- [BJOI2011]禁忌 --- AC自动机 + 矩阵优化 + 期望
bzoj 2553 [BJOI2011]禁忌 题目描述: Magic Land上的人们总是提起那个传说:他们的祖先John在那个东方岛屿帮助Koishi与其姐姐Satori最终战平.而后,Koishi ...
- bzoj 2553 [BeiJing2011]禁忌——AC自动机+概率DP+矩阵
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2553 看了题解才会…… 首先,给定一个串,最好的划分方式是按禁忌串出现的右端点排序,遇到能填 ...
- 【BZOJ 2553】[BeiJing2011]禁忌 AC自动机+期望概率dp
我一开始想的是倒着来,发现太屎,后来想到了一种神奇的方法——我们带着一个既有期望又有概率的矩阵,偶数(2*id)代表期望,奇数(2*id+1)代表概率,初始答案矩阵一列,1的位置为1(起点为0),工具 ...
- spoj 1676 AC自动机+矩阵快速
Text Generator Time Limit: 1386MS Memory Limit: 1572864KB 64bit IO Format: %lld & %llu Submi ...
- hdu 2243 考研路茫茫——单词情结 AC自动机 矩阵幂次求和
题目链接 题意 给定\(N\)个词根,每个长度不超过\(5\). 问长度不超过\(L(L\lt 2^{31})\),只由小写字母组成的,至少包含一个词根的单词,一共可能有多少个? 思路 状态(AC自动 ...
随机推荐
- Mysql --初识mysql语句
本节课先对mysql的基本语法初体验. 操作文件夹(库) 增 create database db1 charset utf8;#db1 是数据库的名字 也就是文件夹 查 # 查看当前创建的数据库 s ...
- j2cache笔记
初步理解 eg: https://my.oschina.net/javayou https://my.oschina.net/tinyframework/blog/538363?p=2 https:/ ...
- Swap交换分区概念
什么是Linux swap space呢?我们先来看看下面两段关于Linux swap space的英文介绍资料: Linux divides its physical RAM (random acc ...
- nginx负载均衡后端tomcat无法加载js资源
JS或css无法完全加载 nginx的代理缓存区,默认较小导致部分文件出现加载不全的问题,比较典型的如jQuery框架,可以通过配置调整nginx的缓存区即可.主要参考proxy参数 最终完整配置如下 ...
- Codeforces 576E Painting Edges [分治,并查集]
洛谷 Codeforces 建议阅读这篇博客作为预备.无耻地打广告 思路 与bzoj4025很相似,思路也差不多,可以看上面那篇博客. 仍然是用二分图的充要条件:没有奇环. 然而这题难在每条边的存在时 ...
- pytorch:修改预训练模型
torchvision中提供了很多训练好的模型,这些模型是在1000类,224*224的imagenet中训练得到的,很多时候不适合我们自己的数据,可以根据需要进行修改. 1.类别不同 # codin ...
- vue.js----之router详解(一)
在vue1.0版本的超链接标签还是原来的a标签,链接地址由v-link属性控制 而vue2.0版本里超链接标签由a标签被替换成了router-link标签,但最终在页面还是会被渲染成a标签的 至于为什 ...
- 《剑指offer》 反转链表
本题来自<剑指offer> 反转链表 题目: 输入一个链表,反转链表后,输出新链表的表头. 思路: 需要三个变量,来保存当前节点的,前面节点和反转后的节点. C++ Code: /* st ...
- Niagara workbench 介绍文档---翻译
一. 发现在建立station的时候存在一些问题,所以对技术文档部分做一个详细的了解,在这之前对出现的问题总结一下 1. 在 Windows操作系统中Application Direction中可以 ...
- Winhex数据恢复学习笔记(三)
上次对文件系统进行简单的分析,这次就文件的镜像功能做一介绍 1.首先镜像的概念:镜像就是数据的副本,是原来数据在相同位置上以相同的排列模式生成的拷贝,所以镜像可以用来还原原始数据,代替原始数据工作,镜 ...