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自动 ...
随机推荐
- Light OJ 1012
经典搜索水题...... #include<bits/stdc++.h> using namespace std; const int maxn = 20 + 13; const int ...
- echo和重定向
命令: echo 作用: echo有重复的意思,会在终端中显示参数指定的文字,通常会和重定向联合使用 使用: echo 文字内容 例子: 在终端中显示hello echo hello 命令: > ...
- Android下利用zbar类库实现扫一扫
程序源代码及可执行文件下载地址:http://files.cnblogs.com/rainboy2010/zbardemo.zip Android下常用的条码扫描类库有zxing和zbar,比较了一下 ...
- Spring+SpringMVC+MyBatis的整合
1.基本概念 1.1.Spring Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-On ...
- Hbase理论&&hbase shell&&python操作hbase&&python通过mapreduce操作hbase
一.Hbase搭建: 二.理论知识介绍: 1Hbase介绍: Hbase是分布式.面向列的开源数据库(其实准确的说是面向列族).HDFS为Hbase提供可靠的底层数据存储服务,MapReduce为Hb ...
- ECS分区挂载数据盘
地址:https://help.aliyun.com/document_detail/25426.html?spm=5176.11065259.1996646101.searchclickresult ...
- js——作用域和闭包
1. js是编译语言,但是它不是提前编译,编译结果不能在分布式系统中移植.大部分情况下,js的编译发生在代码执行前的几微秒(甚至更短) 2. 一般的编译步骤 分词/词法分析:把字符串分解成词法单元 ...
- nginx实践(五)之代理服务(正向代理与反向代理介绍)
正向代理 正向代理代理是为客户端服务,代理负责DNS解析域名到对应ip,并进行访问服务端,返回响应给客户端 反向代理 客户端自己负责请求DNS解析域名到对应ip,服务端通过代理分发流量,进行负载均衡 ...
- python之vscode配置开发调试环境
在vscode中下载python插件,下载量最多的就是 打开launch.json,把以下代码粘贴进去即可 { // 使用 IntelliSense 了解相关属性. // 悬停以查看现有属性的描述. ...
- SpringMVC视图及REST风格
点击进入第二章:SpringMVC基础配置 什么是视图解析器? springMVC用于处理视图最重要的两个接口是ViewResolver和View. ViewResolver的主要作用是把一个逻辑上的 ...