甲:ABC214 F - Substrings

乙:ARC117 C - Tricolor Pyramid

丙1:ARC110 E - Shorten ABC

丙2:AGC027 E - ABBreviate

丁:ABC171 F - Strivore

戊:CF1481 E - Sorting Books

己:ARC112 E - Cigar Box

庚:ABC234 F - Reordering

甲 解1

设\(f_i\)表示选择了第\(i\)个字符,前缀\(S[1\dots i]\)的答案子序列个数。

一种想法是将每个\(f_j,j<i-1\)都统入\(f_i\)中,但这样会导致算重复。

那么我们修改一下原来的定义:

设\(f_i\)表示选择了第i个字符,字符串\(T\)是\(S[1\dots i]\)的答案子序列,并且\(T\)不是\(S[1\dots (i-1)]\)的答案子序列。

换种说法,状态\(f_i\)表示前缀\(S[1\dots i]\)与前缀\(S[1\dots (i-1)]\)的差集。

  • 这个做法好像叫序列自动机

那么继续写下一个\(\color{#ffffff}{假}\)做法x

一个转移:

\(f_i=\sum_{j=1}^{i-2}f_j+1\)

那么我们来证明一下这个\(\color{#ffffff}{假}\)做法的正确性:

  • 根据定义,\((1\dots(i-2))\)统计的答案子序列互相之间不会重合。全都在后面加一个\(s_i\)同理。

  • 假设存在一个字符串被同时统计进了\(f_i\)与某个\(f_j(j<i)\)中,那么这个字符串形如\(T+s_i\)。

    当然也可以写为\(T+s_j\)。也就是\(s_i=s_j\)。

    可以确定的是,这里的\(T\)包含于\((1...(j-2))\)这样一个前缀中。(这个\(T\)可以为空,不多解释)

    所以我们可以确定:\(f_i\)不能由\(f_{1...j-2},s_j=s_i\)转移过来。

进一步更新这个做法:

\(f_i=\sum_{max_j(s_j=s_i)-1}^{i-2}f_j\)

特别地,对于\(s_i\)在字符串第一次出现,\(f_i=\sum_{j=1}^{i-2}f_j+1\)。

证法同上了。

这样 应该 可以了吧x

甲 解2

更简单的一种使得答案不重的思路是,强制规定选出来的子串在原串中最早出现

每个位置转移到后面最近的分别26个字符即可。

事实上,丙丁两题的思想与这个差不多(

将\(RBW\)三种颜色分别标为\(0\),\(1\),\(2\)

两块合并的操作会等价变为两数之和取负\(mod \ 3\)

于是可以把所有块都合并起来再\(mod \ 3\)得到结果。

问题其实转化为一个块到顶端的路径数,在边平行于金字塔的斜平行四边形中讨论发现是二项式系数(

由于这里的模数\(p\)为一个很小的数。当模数小于组合数中的\(n\),\(m\)时,在阶乘中模去\(p\)显然会在某个地方开始出现阶乘为0的情况,将无法处理。

对于这种模数\(p\)小于\(n\),\(m\)的情况,需要用到\(\text{Lucas}\)定理:\({n \choose m} \ mod \ p \ = {{{\frac{n}{p}} \choose {\frac{m}{p}}} \times {{n \ mod \ p} \choose {m \ mod \ p}}} \ mod \ p\)

丙2

题意:给定一个 \(a,b\) 构成的字符串 \(s\),每次可以选择两个连续的 \(a\) 换成 \(b\),或两个连续的 \(b\) 换成 \(a\),问可以构造出多少不同的字符串。

首先我们容易看出,形如\(\text{ababab}\dots\) 的 \(s\) 是无法操作的,此时答案为\(1\)。

在下面,我们不再讨论这样一种特殊情况。

与乙题解法类似,我们设\(mod3\)意义下的\(p(s)\):

设\(p(a)=1\),\(p(b)=2\),\(p(s)\)为s中所有字母\(p\)值和\(mod3\)

那么\(p(aa)=p(b)=2\),\(p(bb)=p(a)=1\),正好对应了合并的这样一个操作。

一个结论:一个字符串\(s\),若其中存在两个相邻且相同的字符,那么s一定可以合并为单个字符串\(c\),且\(p(c)=p(s)\)。

那么我们可以设想一种方法:将一个字符串\(s\)划分为\(m\)个\(p\)值都不为\(0\)的子段,再将每个子段合并。

证明:任意一种可行的划分都可以成功合并。
  • (1) 对于每个子段都存在相邻两个字母相同的划分____可以。
  • (2) 否则,划分出不满足此条件的子段必定为\(\text{abab}\dots\text{baba}\)或者\(\text{baba}\dots\text{abab}\)这样首尾相同的交替串。

    由于两情况对等,我们首先考虑\(\text{abab}\dots\text{baba}\),并特殊化为\(\text{aba}\)(合并后为\(\text{a}\))的形式,并且原串内两个相邻相同的字符在该子段的右边(在左边同理,并且不需要考虑相同字符被合并完了,因为那样可以把它拆回去。)

    此时我们考虑到右边到第一对相同字符的位置为止。

    ① 合并后为\(\text{a}|\text{a}\dots\),则将\(\text{aba}|\text{a}\dots\)中\(\text{ba}|\text{a}\)的部分合并为\(\text{a}\)。

    ② 合并后为\(\text{a}|\text{baba}\dots\text{ababaa}\),合并\(\text{baa}\)为\(\text{a}\)。末尾为\(\text{bb}\)同理
证明结束。

接着我们考虑分段重合的情况。

如果存在一个字符串\(t\),满足\(p(t)=0\)

那么\((s1)(t)(s2)\)这样的情况下,\((s1)(t)|(s2)\)和\((s1)|(t)(s2)\)这两种划分是一样的(p值是一样的)。

那么我们强制规定左侧的子段\(s1\)不含有\(p\)值为\(0\)的非空后缀。

这样划分出来可能会导致全串最后剩下一个\(p\)值为0的后缀。但它可以被合掉(不写证明了,被自己废话恼了)

于是就可以\(\text{DP}\)了

设\(f_i\)表示原串\(1 \dots i\)位置的答案

处理每个位置\(i\),从\(i+1\)位开始 最短的\(p\)值为\(1\)与\(p\)值为\(2\)的串 的末尾 的位置\(nex_{i,1/2}\)。

那么转移是\(f_i \to f_{nex}\)

答案为每个\(p(s{(i+1) \dots n})=0\)的\(f_i\)之和。

另一道题其实类似,令\(p(a)=1\),\(p(b)=2\),\(p(c)=3\),那么两个字母合并的操作就变成了异或(\(\oplus,xor\)),和这题有基本一致的性质。

我们考虑最朴素的做法:选择任意\(k\)个字符插入该字符串任意位置,具体实现是排列完使用隔板法。

但这样会导致答案重复。

于是我们考虑一个最终情况的字符串,例如\(\text{minoriko}\),原串\(\text{io}\)

由\(\text{io}\)到\(\text{minoriko}\)有三种方式:(手写列一下好了)

那么为了使得答案不重,一种思路是:使得\(\text{io}\)到\(\text{minoriko}\)只有一种方法。

也就是\(\text{m} \color{red}{\text{i}} \text{n} \color{red}{\text{o}} \text{riko}\)

那么就得到一个做法:每个字母前面只能插入和它不相同的字符。最后一个字符串后面则可以插入任何字符。

由此得来有意思的结论是,相同长度的字符串得到的答案是相同的。

所以,我们枚举插入在字符串最后的字符个数,再使用隔板法就好了。

得到柿饼:

\[\sum_{i=0}^{k}26^i\times25^{k-i}\times C(n+k-i-1,n-1)
\]

当我们选择了一些需要移动的书本,这些书本放到末尾的顺序是可以任意决定的。

在需要移动的书本之外,自然是选择不需要移动的书本。

不需要移动的书本呢,会是一组一组并不互相重合的相同颜色的区间

不过这里有一个特殊情况,就是最后在所有不移动书本的末尾,由于【任意决定顺序】这个性质,这个末尾并不需要包含全部的该颜色书。

设\(f_i\)表示\([i,n]\)区间最多不移动的书本数目,得到以下转移:

\[f_i=max\left\{
\begin{aligned}
f_{i+1}\\
sumr_{a_i}\\
sumr_{a_i}+f_{r_{a_i}+1}\\
\end{aligned}
\right.
\]

移动问题的\(\text{point}\):选择出移动的元素和不移动的元素。

由原串到目标的这样一个变换,我们可以认为目标串中的某个不降子序列没有被移动过。

首先这题有和戊题一样的一个点,移动的元素顺序可以任意决定

另外,对于某个元素,影响其状态的是只有其最后一次操作。

为了方便,我们暂时称这个元素的最后一次操作为它的关键操作。

研究这个操作的一些性质。

如果在原序列中某一个元素\(x\)完成了其向左的关键操作,那么在目标序列中,\(x\)左侧的元素是必定要操作的。同理,另一个元素完成向右的关键操作,在关键序列中在其右侧的元素也必须进行操作。

在这两个元素之间的所有元素,则不会进行任何操作。

于是我们得到了可以作为不移动的元素的特征:是一组在目标串中连续的元素,并且在目标串中单调递增(准确来说是:元素相对于原串的位置单调递增,由于这里原串元素是单增排列所以可以这样写)

接着考虑移动的元素,会如何移动:

1.完成一个左移关键操作(在不移动元素被确定,当前序列在某个方案中确定的情况下,方案是唯一的。也可以理解为,所有元素完成关键操作的顺序是确定的);

2.完成一个右移关键操作(同左移);

3.不完成任何关键操作(在移动元素中任选一个向左或向右移都可以)。

计数的时候可以只考虑移动的元素。所以我们在下面研究转移的时候,可以将序列看作只包含需要移动的元素。作这个说明只是为了在计数的时候更加清晰

这样得到一个朴素的\(\text{DP}\):

设\(f_{i,l,r}\)表示进行了\(i\)次操作,有\(l\)个元素还未完成左移关键操作,\(r\)个元素还未完成右移关键操作时的操作方案数,那么:

\[f_{i,l,r}=f_{i-1,l,r}\times(l+r)\times2+f_{i-1,l+1,r}+f_{i-1,l,r+1}
\]

答案即\(f_{m,0,0}\)。

我们发现后两项左移右移的转移类似,即左移操作和右移操作本质是一种对称的操作,那么我们可以进一步优化

只关注还有多少个元素未发生关键操作。设\(f_{i,l+r}\)表示进行了\(i\)次操作,有\(l+r\)个元素还未完成关键操作时的操作方案数。

对于结果\(f_{m,0}\),由于我们没有考虑左移右移的操作的顺序,需要乘上\({l+r}\choose l\)(即从\(l+r\)个操作中选出\(l\)个向左,其余向右)。

但我们注意到,这个\(\text{DP}\)的初始状态为\(f_{0,l+r}=1\),对于每一组\(j=l+r\),都需要重新进行\(\text{DP}\),造成了三次的时间复杂度,无法通过。

反过来考虑(倒序还原),使\(\text{DP}\)的初始状态为\(f_{0,0}=0\),即:设\(f_{i,l+r}\)表示还有\(i\)次操作,有\(l+r\)个元素还未完成关键操作时的操作方案数。

与上面相同的考虑移动的方法(这里考虑的是后面这一步做了什么,反推前面这一步):

1.(在下一步中)完成了一个左移关键操作;

2.(在下一步中)完成一个右移关键操作;

3.(在下一步中)不完成任何关键操作,回退到上一步则为选取两端元素之一插回原序列的任意位置。方案数为\((l+r)\times2\)

使用刷表法转移(这里\(l+r\)写作\(j\),实际实现也是这样。\(l\)与\(r\)的拆分只在最后组合数那一步的计算需要用到):

\[f_{i,j} \times j \times 2 \to f_{i+1,j}
\]
\[f_{i,j} \to f_{i+1,j+1}
\]

当然,填表也行(

\[f_{i,j}=f_{i-1,j}\times 2 \times j + f_{i-1,j-1}
\]

突然加的(

设\(f_i\)表示构造长度为\(i\)字符串的方案数

枚举每个字母添加的个数\(k\),那么有:

\[{f_i \times {{i+k} \choose k}} \to f_{i+k}
\]

没了(

【KFC】JZ408 Koufu Contest 3 题解的更多相关文章

  1. AtCoder Beginner Contest 154 题解

    人生第一场 AtCoder,纪念一下 话说年后的 AtCoder 比赛怎么这么少啊(大雾 AtCoder Beginner Contest 154 题解 A - Remaining Balls We ...

  2. AtCoder Beginner Contest 153 题解

    目录 AtCoder Beginner Contest 153 题解 A - Serval vs Monster 题意 做法 程序 B - Common Raccoon vs Monster 题意 做 ...

  3. AtCoder Beginner Contest 177 题解

    AtCoder Beginner Contest 177 题解 目录 AtCoder Beginner Contest 177 题解 A - Don't be late B - Substring C ...

  4. AtCoder Beginner Contest 184 题解

    AtCoder Beginner Contest 184 题解 目录 AtCoder Beginner Contest 184 题解 A - Determinant B - Quizzes C - S ...

  5. M-SOLUTIONS Programming Contest 2020 题解

    M-SOLUTIONS Programming Contest 2020 题解 目录 M-SOLUTIONS Programming Contest 2020 题解 A - Kyu in AtCode ...

  6. AtCoder Beginner Contest 173 题解

    AtCoder Beginner Contest 173 题解 目录 AtCoder Beginner Contest 173 题解 A - Payment B - Judge Status Summ ...

  7. AtCoder Beginner Contest 172 题解

    AtCoder Beginner Contest 172 题解 目录 AtCoder Beginner Contest 172 题解 A - Calc B - Minor Change C - Tsu ...

  8. AtCoder Beginner Contest 169 题解

    AtCoder Beginner Contest 169 题解 这场比赛比较简单,证明我没有咕咕咕的时候到了! A - Multiplication 1 没什么好说的,直接读入两个数输出乘积就好了. ...

  9. AtCoder Beginner Contest 148 题解

    目录 AtCoder Beginner Contest 148 题解 前言 A - Round One 题意 做法 程序 B - Strings with the Same Length 题意 做法 ...

  10. AtCoder Beginner Contest 115 题解

    题目链接:https://abc115.contest.atcoder.jp/ A Christmas Eve Eve Eve 题目: Time limit : 2sec / Memory limit ...

随机推荐

  1. js 实现全屏预览(F11功能)--转

    参考文档   http://t.zoukankan.com/ghfjj-p-6322415.html HTML代码 <body> <div id="content" ...

  2. 初识 Linux Shell

    初识 Linux Shell 本书学习的第一步,就是要找到 Linux 终端的所在位置.目前较常见的图形化终端有 Konsole.Gnome terminal.xterm 等几种.一般安装后在各个发行 ...

  3. Phpstorm 最新永久激活教程

    使用ja-netfilter激活Jetbrains系列软件 注意:无限试用脚本已经失效.本教程适合2021.3.*之上的高版本,使用ja-netfilter插件进行激活操作,永久有效 激活步骤: 第一 ...

  4. C++11新特新-varitable template

    C++11新特新-varitable template应用 可变参模板原理可以仔细阅读C++primer 第5版相关部分 应用1 一个万用的HashFun 通过不断调用可变模板函数进行参数包的运算,最 ...

  5. Java包机制与文档注释

    Java包机制与文档注释 包机制 为了更好地组织类,java提供包机制,用于区分类名的命名空间 包语句的语法: package pkg1.pkg2.pkg3...; // 必须在文件第一行 一般用公司 ...

  6. Lombok和MapStruct冲突

    Lombok和MapStruct冲突导致无法生成正确的class文件. lombok自动生成getset等冗余代码. MapStruct对象copy.传统的BeanUtils.copy等利用的反射原理 ...

  7. clickhouse 安装部署(linux)

    1.安装部署 1.1下载文件 可以按照官网步骤安装 https://clickhouse.tech/docs/zh/getting-started/install/. 这个库目前大小有2G,网络不允许 ...

  8. manu check RAID GEM count and Fragment count of local FN>1

    cat MANU_CHK.sh echo "input Chr" read C echo "input Start" read S echo "inp ...

  9. 自定义组件中使用half-screen-dailog 无法舒勇外部样式

    为了将弹窗更方便的调用,封装了组件,但是发现一个问题, 外部样式类在组件中是无法正常使用的. 也就说在组件的wxss中是无法正常使用.weui-half-screen-dialog 这个外部样式类,然 ...

  10. .net Core5.0使用IdentityServer4 进行权限控制

    .net Core5.0使用IdentityServer4 进行权限控制 IdentityServer4  ASP.NET Core的一个包含OpenID Connect和OAuth 2.0协议的框架 ...