Codeforces 杂题选做

*2500 to *3000。

Problem A. CF1511G Chips on a Board

难度:\(2700\)

解法:

非常厉害的一个题。

首先我们发现问题等价于 nim 游戏,我们只需要求 \(\bigoplus \limits_{i=1}^n (c_i-l)[c_i \geq l \land c_i \leq r]\),即在 \([l,r]\) 范围中的数减去 \(l\) 的异或。如果这个值为 \(0\),那么 Alice 必败,否则 Alice 必胜。

但是这个东西还是不太好求。有一个一眼无脑的做法,我们考虑莫队,发现指针移动只需要维护一棵 01-Trie,支持插入,删除,全局加减 \(1\),求全局异或。这个是经典问题,至此我们得到了 \(O(n \sqrt{n} \log{n})\),适当卡常据说可以通过,但显然我没通过。

正解比较厉害。

我们考虑倍增,\(f_{i,j}\) 表示值在 \([i,i+2^j)\) 内的数减去 \(i\) 后异或的结果。我们要处理的是区间合并的问题。

考虑 \(f_{i,2^j}\)\(f_{i+2^j,2^j}\) 如何合并。我们发现,后面这段区间 \([i+2^j,i+2^{j+1})\) 区间内减去 \(i+2^j\) 后的数都在区间 \([0,2^j)\) 内,且两两不同。现在我们要把他们的值都加上 \(2^j\),也就是合并到前面区间内,可以发现二进制下其他位置都不变,只有 \(2^j\) 这一位都从 \(0\) 变成了 \(1\)。于是额外维护 \(g_{i,j}\) 表示 \([i,i+2^j)\) 这一段的数的个数即可维护转移。

询问的时候按照类似的方法合并区间答案即可。这里合并的区间长度不相等,但是前面区间长度大于后面的,也可以一样转移。

Submission Link

Problem B. CF1511F Chainword

难度:\(2700\)

首先对所有字符串建立字典树。设根节点为 \(0\)。字典树节点大小量级为 \(O(n \left| s \right|)\)

首先有一个朴素的类似数位 DP 的做法,记 \(f_{i,x,y}\) 表示长度为 \(i\),目前未匹配的末尾中 \(P\) 沿着字典树走到了 \(x\)\(Q\) 沿着字典树走到了 \(y\) 时的方案数。转移的时候直接枚举选什么然后转移即可。复杂度 \(O(mn^2\left| s\right|^2\left| \sum \right|)\),显然不对。

注意到这个东西可以直接使用矩阵快速幂优化,这个转移矩阵是一个 \((n\left|s\right|)^2\times(n\left|s\right|)^2\) 的矩阵,直接矩阵快速幂复杂度是 \(O((n\left|s\right|)^6\log m)\),还是不太对。

分析一下可知复杂度瓶颈在于矩阵状态数。事实上我们发现 \(f_{i,x,y}=f_{i,y,x}\),所以通过限制 \(x\leq y\) 可以使得矩阵大小至少可以减半。同时我们可以发现存在大量无用状态 \(f_{i,x,y}=0\),真正有用的状态数不多。可以先进行一次 DFS 或 BFS,从 \((0,0)\) 开始,每次选下一个字符然后在字典树上面走,搜出所有有效状态。现在状态数不会很大,事实上写一下就能过了。

Submission Link

Problem C. CF1510J Japanese Game

难度:\(2700\)

感觉比较直接的一个题啊,想法应该没有什么岔路可走吧。

显然地你需要考虑对于固定的 \(p\),哪些位置是必须要填的。当然对于每个位置你有一个 \(O(n)\) 的判断方式,就是强制这个点不选然后从前往后贪心。但这个东西不容易推广到式子里,自然就不好继续下去。

观察一下发现我们删掉一个位置的后果的其实是一部分格子被浪费。具体来说应该是,我们按照最优策略先将 \(p\) 填进去后,这个位置所在连续黑色段的那段前缀。简单手玩可以发现假设最优策略填完 \(p\) 最后还剩下了 \(x\) 个白色空格,那么这个最优策略中每个极长连续黑色段的第 \(x+1\) 个位置一直到这段结束都是必选位置,其他位置都不是必选位置。即每个极长黑色连续段有一段定长的前缀不是必选位置,然后那段后缀都是必选的。注意如果段长小于等于 \(x\),那么整段都是非必选的。

然后一个直接想法是枚举 \(x\)。但是这样看着复杂度不太对。事实上 \(x\) 必然有个上界,具体来说需要考虑给定的 \(m\) 图中的黑色连续段之间,以及最前面和最后面的,这个地方细节挺多的,但推一推就出来了。

确定了 \(x\) 的上界,我们从大到小枚举 \(x\),此时可以注意到我们要做的就是段与段之间的。这部分直接填 \(01\) 交错就好。特别注意这里和段与段之间长度奇偶性有关,推一下就好。如果 \(x\) 合法就输出,不然继续枚举直到 \(-1\)

事实上你发现 \(x\) 取我们求出的上界通常是优的,除非你发现有时候选了 \(x\) 会导致两端之间粘合在一起,比如两端中间只有两个位置没选,此时没办法构造,从而 \(x\) 要减少。这个地方可以在预处理的时候求出一个合法的 \(x\) 从而只需要一次构造即可。

总复杂度 \(O(n)\),好想但细节一车。

Submission Link

Problem D. CF1510I Is It Rated?

难度:\(2700\)

不知道为啥会出这种题,可能 ICPC 就是这样吧。

完全想不出来,写了一堆乱搞过不去,于是点开了官方题解,看见了一个维基百科的链接,介绍的就是这个问题,做法是一个什么人工智能的机器学习算法,这里简单翻译一下过程:

  • 初始时,给所有人一个权重 \(w_i=1\)

  • 每一次答题时,设这个题选 \(0\) 的人的权重和为 \(x\),选 \(1\) 的人的权重和为 \(y\)。以 \(\dfrac{x}{x+y}\) 的概率选择 \(0\),否则选择 \(1\)

  • 宣布答案后,将所有答错的人的权重乘以常数 \(\beta\)。其中 \(0 < \beta < 1\)

此题中取 \(\beta = 0.8\) 即可通过,事实上这其实很符合直觉,但是自己发明这种东西似乎还是有点困难的。证明有点太过抽象了,有兴趣的可以自己翻官方题解看看。

Submission Link

Problem E. CF1508C Complete the MST

难度:\(2500\)

\(s\) 为目前给定的 \(m\) 条边的边权异或和,考虑最终答案会是怎么样的。

一个比较容易看出的观察是我们只会在图上加一条边权为 \(s\) 的边,其余的边权都是 \(0\) 即可。

考虑先进行补图 BFS 求出图被给定的边分成的每个连通块。每条给定边要么是横跨连通块,要么是连通块内部。

连通块内部的边没有意义,考虑用他们之间的边求一个 MST。

现在你要把一条边改为 \(s\),图上总共有 \(\dbinom{n}{2} = \dfrac{n(n-1)}{2}\) 条边,给定了 \(m\) 条边,答案的 MST 最坏情况下一条指定的边都不用,总共有 \(n-1+m\) 条边要用。如果 \(\dbinom{n}{2} > n-1+m\),那么新加的边必然可以有个位置选而同时不影响答案。

如果 \(\dbinom{n}{2} \leq n+m-1\),发现此时 \(m\)\(O(n^2)\) 的量级,直接枚举选哪两个点连 \(s\) 然后重新跑 MST 即可。

Submission Link

posted @ 2024-06-08 12:26  HappyBobb  阅读(7)  评论(0)    收藏  举报