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

bzoj 2553 [BJOI2011]禁忌

题目描述:

Magic Land上的人们总是提起那个传说:他们的祖先John在那个东方岛屿帮助Koishi与其姐姐Satori最终战平。而后,Koishi恢复了读心的能力……

如今,在John已经成为传说的时代,再次造访那座岛屿的人们却发现Koishi遇到了新麻烦。

这次她遇到了Flandre Scarlet——她拥有可以使用禁忌魔法而不会受到伤害的能力。

为了说明什么是禁忌魔法及其伤害,引入以下概念:

1.字母集A上的每个非空字符串对应了一个魔法。

其中A是包含了前alphabet个小写字母的集合。

2.有一个集合T,包含了N个字母集A上的字符串

T中的每一串称为一个禁忌串(Taboo string

3.一个魔法,或等价地,其对应的串s因为包含禁忌而对使用者造成的伤害按以下方式确定:

s分割成若干段,考虑其中是禁忌串的段的数目,不同的分割可能会有不同的数目,其最大值就是这个伤害。

由于拥有了读心的能力,Koishi总是随机地使用Flandre Scarlet的魔法,可以确定的是,她的魔法正好对应字母集A上所有长度为len的串

但是,Flandre Scarlet所使用的一些魔法是带有禁忌的,由于其自身特性,她可以使用禁忌魔法而不受到伤害,而Koishi就不同了。

可怜的Koishi每一次使用对方的魔法都面临着受到禁忌伤害的威胁。

你现在需要计算的是如果Koishi使用对方的每一个魔法的概率是均等的,那么每一次随机使用魔法所受到的禁忌伤害的期望值是多少。

输入格式:

第一行包含三个正整数Nlenalphabet

接下来N行,每行包含一个串Ti,表示禁忌串。

输出格式:

一个非负实数,表示所受到禁忌伤害的期望值。

数据范围:

100%的数据中N ≤ 5len ≤1091 ≤ alphabet ≤ 26

在所有数据中,有不少于40%的数据中:N = 1

数据保证每个串Ti的长度不超过15,并且不是空串。

数据保证每个Ti均仅含有前alphabet个小写字母。

数据保证集合T中没有相同的元素,即对任意不同的ij,有TiTj

评分方法:

对于每一组数据,如果没有得到正确的输出(TLE、MLE、RTE、输出格式错误等)得0分。

否则:设你的输出是YourAns,标准输出是StdAns

MaxEPS = max(1.0 , StdAns)×10-6

如果|YourAns – StdAns| ≤ MaxEPS则得10分,否则得0分。

即:你的答案需要保证相对误差或绝对误差不超过10-6

(不开 long double 不让过)

AC自动机最后一题。

(2011年的题比2017年的题难。。。)

先考虑一个字符串构成的权值。

一个字符串构成的权值??

动态规划??不好统计。

贪心??仿佛是。

怎么贪?

建成AC自动机,只要匹配到就返回根继续匹配。

为什么没有更优?

当我们优先选择在最前面,最短的那个可以匹配上的禁忌串时,后面的禁忌串是不可能出现的。

或者说,如果匹配串中的子串\([l,r]\)同时被多个串覆盖,那么,它要么被最前面的串匹配掉,要么被更前面的串匹配掉。

所以自然地最优。

知道了权值怎么来的,自然还要知道怎么统计。

设状态\(dp(i,j)\)表示长度为i, 状态为j的期望权值。

那么考虑转移造成的贡献,如果是禁忌串的结尾,那么就可以获得 \(1/alphabet\)的期望。

否则就转移吧。

注意到\(L\)非常大,需要矩阵优化。

转移矩阵怎么构造?

\(sum\)(老状态期望 * P(老状态 ---> 新状态))= 新状态期望

因此,不难想到设\(a(i,j)\)表示由\(i\)状态转移到\(j\)状态的概率来转移。

\(a(i,j)\)是可以预处理的。

完了吗?

并没有。

我们并没有办法得出最终的答案。

\(a(root,...)\)已经被我们用来算概率了,它失去了统计期望的本事。

因此,我们需要一个专门来统计答案的点:\(daan\)

用\(daan\)来统计期望。

现在,每个点匹配到了禁忌串要返回根,先走过它来统计答案。

现在\(a(i,daan)\)表示从\(i\)走x步到一个禁忌串的期望

因此,\(a(root,daan)\)就是每次的期望(根走\(x\)步走到禁忌串的期望)

为了方便统计答案,需要设\(a(daan,daan)=1\)。

为什么?

因为\(a(i,daan)=E(now)+a(i,daan)*a(daan,daan)\)

(\(E(now)\)其实也是用\(daan\)来统计期望,而\(a(daan,daan)=1\)保证了可以维护前面的期望(期望的线性性质))

那么我们既能让根节点正常地参与概率转移矩阵的运算,又能统计答案。

\(daan\)相当于一个矩阵中的计数器

何乐而不为?

原文地址:https://www.cnblogs.com/reverymoon/p/8887572.html

时间: 2024-08-30 00:48:52

AC自动机 + 矩阵优化 + 期望 --- [BJOI2011]禁忌的相关文章

AC自动机 + 矩阵优化 --- [BJOI2017]魔法咒语

bzoj 4860   LOJ2180   洛谷P3175 [BJOI2017]魔法咒语 题目描述: Chandra 是一个魔法天才. 从一岁时接受火之教会洗礼之后,Chandra 就显示出对火元素无与伦比的亲和力,轻而易举地学会种种晦涩难解的法术. 这也多亏 Chandra 有着常人难以企及的语言天赋,让她能轻松流利地说出咒语中那些极其拗口的魔法词汇. 直到十四岁,开始学习威力强大的禁咒法术时,Chandra 才遇到了障碍. 根据火之魔法规则,禁咒的构成单位是 N 个基本词汇. 施法时只要凝聚

poj2778--DNA Sequence(AC自动机+矩阵优化)

DNA Sequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 12252   Accepted: 4661 Description It's well known that DNA Sequence is a sequence only contains A, C, T and G, and it's very useful to analyze a segment of DNA Sequence,For ex

poj2778DNA Sequence(AC自动机+矩阵乘法)

链接 看此题前先看一下matrix67大神写的关于十个矩阵的题目中的一个,如下: 经典题目8 给定一个有向图,问从A点恰好走k步(允许重复经过边)到达B点的方案数mod p的值    把给定的图转为邻接矩阵,即A(i,j)=1当且仅当存在一条边i->j.令C=A*A,那么C(i,j)=ΣA(i,k)*A(k,j),实际上就等于从点i到点j恰好经过2条边的路径数(枚举k为中转点).类似地,C*A的第i行第j列就表示从i到j经过3条边的路径数.同理,如果要求经过k步的路径数,我们只需要二分求出A^k

poj 2778 AC自动机 + 矩阵快速幂

// poj 2778 AC自动机 + 矩阵快速幂 // // 题目链接: // // http://poj.org/problem?id=2778 // // 解题思路: // // 建立AC自动机,确定状态之间的关系,构造出,走一步 // 能到达的状态矩阵,然后进行n次乘法,就可以得到状态间 // 走n步的方法数. // 精髓: // 1):这个ac自动机有一些特别,根节点是为空串,然而 // 每走一步的时候,如果没法走了,这时候,不一定是回到根 // 节点,因为有可能单个的字符时病毒,这样

spoj 1676 AC自动机+矩阵快速

Text Generator Time Limit: 1386MS   Memory Limit: 1572864KB   64bit IO Format: %lld & %llu Submit Status Description LoadingTime has been given a task these days. He is required to write a tool called Text Generator. This software is widely used amon

hdu2243 ac自动机+矩阵连乘

http://acm.hdu.edu.cn/showproblem.php?pid=2243 Problem Description 背单词,始终是复习英语的重要环节.在荒废了3年大学生涯后,Lele也终于要开始背单词了. 一天,Lele在某本单词书上看到了一个根据词根来背单词的方法.比如"ab",放在单词前一般表示"相反,变坏,离去"等. 于是Lele想,如果背了N个词根,那这些词根到底会不会在单词里出现呢.更确切的描述是:长度不超过L,只由小写字母组成的,至少包

POJ 2778 DNA Sequence (AC自动机 + 矩阵快速幂)

题目链接:DNA Sequence 解析:AC自动机 + 矩阵加速(快速幂). 这个时候AC自动机 的一种状态转移图的思路就很透彻了,AC自动机就是可以确定状态的转移. AC代码: #include <iostream> #include <cstdio> #include <queue> #include <cstring> using namespace std; const int MOD = 100000; struct Matrix{ int ma

POJ POJ 2778 DNA Sequence AC自动机 + 矩阵快速幂

首先建立Trie和失败指针,然后你会发现对于每个节点 i 匹配AGCT时只有以下几种情况: i 节点有关于当前字符的儿子节点 j 且安全,则i 到 j找到一条长度为 1的路. i 节点有关于当前字符的儿子节点 j 且 不安全,则i 到 j没有路. i 节点没有关于当前字符的儿子节点 但是能通过失败指针找到一个安全的节点j,那么 i 到 j 找到一条长度为1的路. 关于节点安全的定义: 当前节点不是末节点且当前节点由失败指针指回跟节点的路径上不存在不安全节点,那么这个节点就是安全节点. 然后问题就

hdu 2243 AC自动机 + 矩阵快速幂

// hdu 2243 AC自动机 + 矩阵快速幂 // // 题目大意: // // 给你一些短串,问在长度不超过k的任意串,包含至少一个这些短串的其中 // 一个.问这样的串有多少个. // // 解题思路: // // 首先, 包含和不包含是一种互斥关系,包含+不包含 = 全集u.全集的答案就是 // 26 ^ 1 + 26 ^ 2 + .... + 26 ^ k.不包含的比较好求.构建一个自动机,得到 // 一个转移矩阵A.表示状态i能到状态j的方法数.而这些状态中都是不包含所给的 //