【KFC】JZ408 Koufu Contest 3 题解
甲: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}\)
那么就得到一个做法:每个字母前面只能插入和它不相同的字符。最后一个字符串后面则可以插入任何字符。
由此得来有意思的结论是,相同长度的字符串得到的答案是相同的。
所以,我们枚举插入在字符串最后的字符个数,再使用隔板法就好了。
得到柿饼:
戊
当我们选择了一些需要移动的书本,这些书本放到末尾的顺序是可以任意决定的。
在需要移动的书本之外,自然是选择不需要移动的书本。
不需要移动的书本呢,会是一组一组并不互相重合的相同颜色的区间
不过这里有一个特殊情况,就是最后在所有不移动书本的末尾,由于【任意决定顺序】这个性质,这个末尾并不需要包含全部的该颜色书。
设\(f_i\)表示\([i,n]\)区间最多不移动的书本数目,得到以下转移:
己
移动问题的\(\text{point}\):选择出移动的元素和不移动的元素。
由原串到目标的这样一个变换,我们可以认为目标串中的某个不降子序列没有被移动过。
首先这题有和戊题一样的一个点,移动的元素顺序可以任意决定
另外,对于某个元素,影响其状态的是只有其最后一次操作。
为了方便,我们暂时称这个元素的最后一次操作为它的关键操作。
研究这个操作的一些性质。
如果在原序列中某一个元素\(x\)完成了其向左的关键操作,那么在目标序列中,\(x\)左侧的元素是必定要操作的。同理,另一个元素完成向右的关键操作,在关键序列中在其右侧的元素也必须进行操作。
在这两个元素之间的所有元素,则不会进行任何操作。
于是我们得到了可以作为不移动的元素的特征:是一组在目标串中连续的元素,并且在目标串中单调递增(准确来说是:元素相对于原串的位置单调递增,由于这里原串元素是单增排列所以可以这样写)
接着考虑移动的元素,会如何移动:
1.完成一个左移关键操作(在不移动元素被确定,当前序列在某个方案中确定的情况下,方案是唯一的。也可以理解为,所有元素完成关键操作的顺序是确定的);
2.完成一个右移关键操作(同左移);
3.不完成任何关键操作(在移动元素中任选一个向左或向右移都可以)。
计数的时候可以只考虑移动的元素。所以我们在下面研究转移的时候,可以将序列看作只包含需要移动的元素。作这个说明只是为了在计数的时候更加清晰
这样得到一个朴素的\(\text{DP}\):
设\(f_{i,l,r}\)表示进行了\(i\)次操作,有\(l\)个元素还未完成左移关键操作,\(r\)个元素还未完成右移关键操作时的操作方案数,那么:
答案即\(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\)表示构造长度为\(i\)字符串的方案数
枚举每个字母添加的个数\(k\),那么有:
没了(