原文链接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自动机 矩阵的更多相关文章

  1. BZOJ2553[BeiJing2011]禁忌——AC自动机+概率DP+矩阵乘法

    题目描述 Magic Land上的人们总是提起那个传说:他们的祖先John在那个东方岛屿帮助Koishi与其姐姐Satori最终战平.而后,Koishi恢复了读心的能力…… 如今,在John已经成为传 ...

  2. bzoj 2553: [BeiJing2011]禁忌 AC自动机+矩阵乘法

    题目大意: http://www.lydsy.com/JudgeOnline/problem.php?id=2553 题解: 利用AC自动机的dp求出所有的转移 然后将所有的转移储存到矩阵中,进行矩阵 ...

  3. 【BZOJ】2553: [BeiJing2011]禁忌 AC自动机+期望+矩阵快速幂

    [题意]给定n个禁忌字符串和字符集大小alphabet,保证所有字符在集合内.一个字符串的禁忌伤害定义为分割能匹配到最多的禁忌字符串数量(一个可以匹配多次),求由字符集构成的长度为Len的字符串的期望 ...

  4. 【BZOJ2553】[BeiJing2011]禁忌 AC自动机+期望DP+矩阵乘法

    [BZOJ2553][BeiJing2011]禁忌 Description Magic Land上的人们总是提起那个传说:他们的祖先John在那个东方岛屿帮助Koishi与其姐姐Satori最终战平. ...

  5. [BJOI2011]禁忌 --- AC自动机 + 矩阵优化 + 期望

    bzoj 2553 [BJOI2011]禁忌 题目描述: Magic Land上的人们总是提起那个传说:他们的祖先John在那个东方岛屿帮助Koishi与其姐姐Satori最终战平.而后,Koishi ...

  6. bzoj 2553 [BeiJing2011]禁忌——AC自动机+概率DP+矩阵

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2553 看了题解才会…… 首先,给定一个串,最好的划分方式是按禁忌串出现的右端点排序,遇到能填 ...

  7. 【BZOJ 2553】[BeiJing2011]禁忌 AC自动机+期望概率dp

    我一开始想的是倒着来,发现太屎,后来想到了一种神奇的方法——我们带着一个既有期望又有概率的矩阵,偶数(2*id)代表期望,奇数(2*id+1)代表概率,初始答案矩阵一列,1的位置为1(起点为0),工具 ...

  8. spoj 1676 AC自动机+矩阵快速

    Text Generator Time Limit: 1386MS   Memory Limit: 1572864KB   64bit IO Format: %lld & %llu Submi ...

  9. hdu 2243 考研路茫茫——单词情结 AC自动机 矩阵幂次求和

    题目链接 题意 给定\(N\)个词根,每个长度不超过\(5\). 问长度不超过\(L(L\lt 2^{31})\),只由小写字母组成的,至少包含一个词根的单词,一共可能有多少个? 思路 状态(AC自动 ...

随机推荐

  1. 谓词逻辑 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 ...

  2. python读写csv文件

    文章链接:https://www.cnblogs.com/cloud-ken/p/8432999.html Python读写csv文件 觉得有用的话,欢迎一起讨论相互学习~Follow Me 前言 逗 ...

  3. Oracle Package的全局变量与Session

    Oracle Package的全局变量与Session2012-07-26 aaie_ 阅 3595 转 10简单讲,同一个session下pageckage中的全局变量时公共的,会导致冲突.以下是一 ...

  4. swiper轮播图(逆向自动切换类似于无限循环)

    swiper插件轮播图,默认的轮播循序是会从右向左,第一张,第二张,第三张,然后肉眼可见是的从第三张从左到右倒回第一张,这样就会有些视觉体验不高, ,不过还是能够用swiper本身的特性更改成无限循环 ...

  5. input file 多张图片上传 获取地址 ——fileReader

    //上传图片 $('#files').change(function(e){ var fil = this.files; var m =0; if(fil.length>3){ alert('重 ...

  6. Logcat命令详情

    logcat是什么? Logcat 是一个命令行工具,用于转储系统消息日志,其中包括设备引发错误时的堆叠追踪以及从您的应用使用 Log类编写的消息. 格式:[adb] logcat [<opti ...

  7. ionic3 打包Xcode 9 Swift Language Version (SWIFT_VERSION) Ask 报错

    解决方案 选择4.0 然后报错17个,类似以下这样的错误 'AVMediaTypeVideo' has been renamed to 'AVMediaType.video' 根据提示更改 AVMed ...

  8. day07 元组类型 字典类型 集合

    元组:元组就是一个不可变的列表 1.用途:当我们需要记录多个同种属性的值,并且只有读的需求,没有改的需求,应该用元组. 2.定义方式:在()内用逗号分隔开多个任意类型的元素 t=(‘egon’)#注意 ...

  9. Mycat实现mysql主从复制(读写分离)

    数据库性能瓶颈主要原因: 随着用户数的增多,带来的是数据库连接的大幅度增长 随着业务体量的增长,表数据量(空间存储的问题)的大幅增长,其中涉及到索引的优化,mysql默认的索引是硬盘级别的,BTREE ...

  10. 安装lrzsz 实现windows与linux之间文件互传

    环境:CentOS7.4 执行命令安装: [root@linuxhg01 www]# yum install lrzsz rz // Windows 上传到 linux [root@linuxhg01 ...