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自动 ...
随机推荐
- 谓词逻辑 p->q 的真假
若p为假,则q可取真或假,p->q为永真 若p为真,q为假,则p->q为假 若p为真,q为真,则p->q为真 p q p->q 0 0 1 0 1 1 1 0 0 1 1 1 ...
- python读写csv文件
文章链接:https://www.cnblogs.com/cloud-ken/p/8432999.html Python读写csv文件 觉得有用的话,欢迎一起讨论相互学习~Follow Me 前言 逗 ...
- Oracle Package的全局变量与Session
Oracle Package的全局变量与Session2012-07-26 aaie_ 阅 3595 转 10简单讲,同一个session下pageckage中的全局变量时公共的,会导致冲突.以下是一 ...
- swiper轮播图(逆向自动切换类似于无限循环)
swiper插件轮播图,默认的轮播循序是会从右向左,第一张,第二张,第三张,然后肉眼可见是的从第三张从左到右倒回第一张,这样就会有些视觉体验不高, ,不过还是能够用swiper本身的特性更改成无限循环 ...
- input file 多张图片上传 获取地址 ——fileReader
//上传图片 $('#files').change(function(e){ var fil = this.files; var m =0; if(fil.length>3){ alert('重 ...
- Logcat命令详情
logcat是什么? Logcat 是一个命令行工具,用于转储系统消息日志,其中包括设备引发错误时的堆叠追踪以及从您的应用使用 Log类编写的消息. 格式:[adb] logcat [<opti ...
- ionic3 打包Xcode 9 Swift Language Version (SWIFT_VERSION) Ask 报错
解决方案 选择4.0 然后报错17个,类似以下这样的错误 'AVMediaTypeVideo' has been renamed to 'AVMediaType.video' 根据提示更改 AVMed ...
- day07 元组类型 字典类型 集合
元组:元组就是一个不可变的列表 1.用途:当我们需要记录多个同种属性的值,并且只有读的需求,没有改的需求,应该用元组. 2.定义方式:在()内用逗号分隔开多个任意类型的元素 t=(‘egon’)#注意 ...
- Mycat实现mysql主从复制(读写分离)
数据库性能瓶颈主要原因: 随着用户数的增多,带来的是数据库连接的大幅度增长 随着业务体量的增长,表数据量(空间存储的问题)的大幅增长,其中涉及到索引的优化,mysql默认的索引是硬盘级别的,BTREE ...
- 安装lrzsz 实现windows与linux之间文件互传
环境:CentOS7.4 执行命令安装: [root@linuxhg01 www]# yum install lrzsz rz // Windows 上传到 linux [root@linuxhg01 ...