Codeforces Global Round 28 官方题解
A. 凯文和湖景村
-
提示 #1
当我们选择连续的两个
3 删除时,这个数减少了多少?
当我们将
所以我们只需要判断
B. 凯文和不归林
-
提示 #1
如果排列足够长,最多能有多少个长度为
k 的子区间的最小值为1 ?
整个排列中,最多只有
对于剩余的位置,可以用
C. 凯文和月亮河公园
-
提示 #1
是否存在一个对于所有串,都必然会被选择的子串?
-
提示 #2
-
提示 #3
注意特殊处理全
1 串。
为了最大化两个串的异或和,肯定想要最大化异或和的二进制位数,为了最大化这个位数,
找到整个串从前往后的第一个
若整个串全部是
有趣的事实:这个题可以做到
在筹备比赛确定题目过程中,我们认为
D. 凯文和里奥的回忆
-
提示 #1
可以忽略所有 rating 低于你的参赛者,这不影响答案。
-
提示 #2
你是 rating 最低的参赛者,所以你能解决的问题所有人都能解决,因此你在一场比赛中的排名只与你不能解决的最简单问题有关。
-
提示 #3
使用贪心算法解决该问题。
阅读所有提示。先删除所有 rating 低于你的参赛者,这样你就成了 rating 最低的参赛者。此时你能解决的问题所有人都能解决,不影响你的排名,可以将这些问题的难度看作
此时,你不能解决任何问题,因此你在一场比赛中的排名是
预处理出对于每个问题,有多少参赛者能够解决,设为
接下来的问题是,给定
E. 凯文和军工厂
-
提示 #1
可以观察到
m 越大条件越难以满足,尝试找到m 的上界。
图总共有
接下来我们只需构造出
事实上容易构造,由于每个右部点的度数为
1 4 4 3 3 2 2
1 1 4 4 3 3 2
2 1 1 4 4 3 3
2 2 1 1 4 4 3
3 2 2 1 1 4 4
3 3 2 2 1 1 4
4 3 3 2 2 1 1
4 4 3 3 2 2 1
因此一种简单的构造方法是对于左部点
F. 凯文和永眠镇
-
提示 #1
能否找到一种策略,使得只有
n 个区间会可能被操作。 -
提示 #2
每次操作整个序列,可以使答案
\le 63 。
对于
- 证明:对于一个
b_x ,找到其左侧最后一个b_p\le b_x 的p 与右侧第一个b_q<b_x 的q ,如果我们希望区间除以b_x ,那么操作区间不能包含p,q 两个位置,同时区间尽可能长肯定不劣,因此必然操作[p+1,q-1] 这个区间。而这些所有区间就是笛卡尔树上的区间。
考虑在笛卡尔树上进行 dp,令
然后再考虑在
由于一直操作整个序列可以做到
这种做法的瓶颈在于对于两棵子树 dp 状态的合并。观察发现
G. 凯文和圣心医院
-
提示 #1
左式能小于右式吗?
-
提示 #2
考虑式子中取到最值的位置,它们有什么性质?
-
提示 #3
考虑容斥原理。
-
提示 #4
二项式定理。
我们假设左式中取到最值的位置为
任意找出一个
考虑两边同时取到最值的位置,记作
不妨枚举最值
朴素计算是
求和符号中很像二项式定理,考虑加上
于是我们在
H. 凯文和唐人街
-
提示 #1
考虑如何确定是否可以生成
01 字符串t 。 -
提示 #2
尝试设计一个只需要记录有用变量的 DP。
-
提示 #3
使用数据结构优化,或优化转移复杂度。
假设对
初始的串
因此从
现在,不妨考虑如何判定
现在考虑进行 DP,设
- 如果
s[j-1,n-i+1] 已经出现了1 ,那么t 反转后的第i 位必须为1 ,且必然p_i=j-1 ,将dp_{i,j-1} 加上dp_{i-1,j} 。 - 如果
s[j-1,n-i+1] 未出现1 ,t 反转后的第i 位可以为0 ,如果为0 必然取p_i=j-1 ,还是将dp_{i,j-1} 加上dp_{i-1,j} ;如果希望t 反转后的第i 位为1 ,需要找到最大的pos \le n-i+1 使得s_{pos} 为1 ,然后取p_i=pos ,将dp_{i,pos} 加上dp_{i-1,j} 。
两类转移可以看作是无论如何将
可以将第一种转移视作对 DP 数组进行了整体平移,然后第二种转移是求 DP 数组一段后缀和再执行一次单点加,记录偏移量后容易使用线段树在
答案即是所有
由于转移有着更好的性质,实际上可以不用数据结构仅仅更巧妙地使用前缀和
I1. 凯文和红教堂(简单版本)
-
提示 #1
讨论最左边和最右边的字符分别是什么,然后递归构造。
引理:假设最后填出来最大值是
证明:首先显然有
考虑序列
- 如果分别是 L 和 R,可以发现这两个位置的数一定都是
0 ,而除了这两个位置一定不能填0 。对于内部的位置,无论是 L 还是 R,都会将0 统计为一种不同的数字。因此我们可以删去这两个位置,对里面递归做,在完成后给里面的所有数字+1 ,并在前后各加入一个0 。 - 如果分别是 L 和 L,首先左边的 L 一定是
0 ,假设右边的 L 写的是x ,容易证明里面的位置不可能填x 。对于内部的位置,无论是 L 还是 R,都会将0 或x 统计为一种不同的数字。 所以和上一种情况类似地,还是删去两端后递归做,然后给里面的数都+1 再填上0 和x 。需要满足x 的值是里面的不同数的个数+1 。此时要求x 在内部不能出现过,根据引理可以发现这个条件等价于,内部整个区间满足d=1 。 - 如果分别是 R 和 R,跟上一种情况相同。
- 如果分别是 R 和 L,可以得到一种简单的构造是全填
1 。同时我们发现,在这种情况下,无论填什么数字都不会出现0 ,因此这个情况只能对应d=0 。
我们把原字符串每次取出首尾字符后递归构造。
分析
因此,考虑最外层的 RL,其外层若包含 LL 或 RR,则无解。
否则一定有解,且容易根据上述过程构造。
复杂度
I2. 凯文和红教堂(困难版本)
-
提示 #1
只有简单版本中两侧字符为 RL 的情况需要计数,事实上 RL 这两个位置上的数一定相同。
-
提示 #2
不妨设 RL 这两个位置填的数是
m ,枚举最右侧填m 的 R 位置x ,和最左侧填m 的 L 位置y 。 -
提示 #3
上述情况中
x>y 的情况容易解决。对于x<y 的情况,分析出其满足条件的充要条件。 -
提示 #4
对于最终转化后的条件,使用 bitset 或卷积来完成计数。
根据简单版本,可以发现大部分情况解的个数并不多,因为对于 LR,LL 和 RR,对于里面的部分填完后,外层只有唯一的填法。因此如果没有一层是 RL,那么答案必然是
接下来考虑有 RL 的情况,不妨假设 RL 是最外部的两个字符。
可以证明的是:这个 RL 中 R 位置和 L 位置填的数是相同的。具体证明在此省略,读者自证不难。
不妨设这个相同的值为
-
若
x>y ,可以发现x 右边的 L 都需要填m ,而x 右边的 R 只有唯一的填法。对y 同理。对这种情况计算,我们可以直接枚举m ,然后就可以确定唯一的x,y 位置,并检查是否满足x>y 。 -
若
x<y ,此时x 左边的 R 都只能填m ,左边的 L 是唯一的填法。对y 的右侧同理。再考虑(x,y) 中间的部分,显然m 必然没有在中间出现,因此我们可以删除x 及其左边的 R,y 及其右边的 L(也就是删除所有值为m 的位置),称得到的新序列为剩余序列。删除这些字符后,我们解决剩余序列,再对得到的数全部+1 ,然后加入所有数为m 的位置即可。以下为一个初始序列的例子,其中红色的字符为
x 和y ,省略的部分是(x,y) 中间的部分。\textbf{R L L R R L L }\color{red}\textbf{R}\color{black}\textbf{ ... }\color{red}\textbf{L}\color{black}\textbf{ L R R L}\\\textbf{ m 1 2 m m 3 4 m ... m m 2 1 m} 以下为上述对应的剩余序列,
* 对应原序列中x,y 的位置。\textbf{L L L L }\color{red}\textbf{*}\color{black}\textbf{ ... }\color{red}\textbf{*}\color{black}\textbf{ R R}\\\textbf{ 1\ 2\ 3\ 4 * ... * 2 \ 1} 在填完剩余序列后,需要分析加入所有数为
m 的位置的条件:我们将剩余序列分为“左”、“中”、“右”三个部分,以x,y 的位置为分界线,其中左部分只有 L,右部分只有 R。则要求是,记“左中”部分的颜色总数为c_1 ,“中右”部分的颜色总数为c_2 ,那么需要满足m=c_1+1=c_2+1 。同时还要求m 不在剩余序列中出现,该限制等价于对于“左中”部分和“中右”部分,都满足d=1 。可以推出等价于剩余序列满足d=1 。对于条件c_1=c_2 ,容易发现其等价于:记z 为左部分和右部分的个数较大值,则剩余序列最左边z 个字符必须全为 L,最右边z 个字符必须全为 R。这部分的最终得出的充要条件是:记
x 左边有a 个 L,y 右边有b 个 R,不妨假设a\ge b ,取出(x,y) 中间的字符串(不包含x,y ),需要满足末尾有连续a-b 个 R,且去这a-b 个 R 后,得到的字符串满足d=1 ,即每次取出首尾字符时不存在 RL 的情况。由于d=1 ,因此若剩余序列满足该条件,则存在恰好一种填法。
最后仅需要对上述情况分别计数即可。
- 当
cnt=0 时,a 的值固定,但对应的x 可以在某一个 R 连续段中任意选择一个位置。我们发现由于cnt=0 ,也就是y 前面一个位置填的是 L,那么x 后面一个位置就不能填 R,所以x 只能取这个 R 连续段中的最后一个 R。 - 当
cnt>0 时,只需要枚举x 的值。容易发现每个x 只会被计算至多2 次。
通过上述观察,我们总共只需要枚举
最后的问题是:每次给定一组区间
一种简单的解决方法是,使用 bitset 维护,例如从小到大扫描
如果使用分块卷积,可以做到更优的复杂度。事实上,如果继续深挖性质,可以做到