2022-2023 杂题乱补

上个赛季没补的题,可能当时确实是看不懂题解在说些什么。不知道这个赛季有没有取得了一点进步呢。

wind_whisper 集训 (2023.1) (76+0)/80

HL 集训 (2023.3) (23+5)/43

CF1451F Nullify The Matrix

Tags: *2700, constructive algorithms, games.

先丢结论:先手必败,当且仅当每个斜线上的数异或和都为 \(0\)
考虑为什么是这样的,类比 Nim 的证明。

  • 对于棋盘全 \(0\) 的局面,先手必败;
  • 对于每个斜线上的数异或和都为 \(0\) 的局面,进行一次操作,一定会使操作起点所在斜线的异或和改变;
  • 对于不都为 \(0\) 的局面,我们以第一个不为 \(0\) 的斜线为起点,一定存在某个决策将必败态丢给后手。

CF1605F PalindORme

Tags: *2900, combinatorics, dp.

为什么只有 *2900 呢。总之就很理解为什么 3 月没补这题,因为确实看不懂!

考虑怎么判定一个已知的序列 \(b\)\(\text{good}\) 的。首先一个边界条件是它可以选出一对相等的数,使得 \(a_1=a_n\)
那么去掉这两个数对 \(\text{or}\) 结果的影响,即为将 \(b\) 中剩下的数所有 \(a_1\) 有的位都变为 \(1\)。这样即消除了 \(a_1\)\(a_n\) 的贡献,可以对长度为 \(n-2\) 的子序列重复上述做法。

概括一下,我们用如下步骤判定一个序列:

  • 在序列中选出两个相等的数 \(x\),并删去它们;
  • 对剩下的所有数,\(b_i\gets b_i \text{ or } x\)
  • 若序列删空,则为 \(\text{good}\) 序列;若找不到相等的数,则为 \(\text{bad}\) 序列;否则返回第一步。

注意到,\(\text{good}\) 序列似乎仍是不好计数的,考虑反过来对 \(\text{bad}\) 序列计数。我们定义一个 \(\text{bad}\) 序列的「最长 \(\text{good}\) 子序列」为其采用上述方法成功删去的数的集合。
可以证明,对于一个 \(\text{bad}\) 序列,与之对应的最长 \(\text{good}\) 子序列也可以唯一确定。
挖掘一下剩下删不掉的序列的性质:除掉已经被删掉的数包含的二进制位外,剩下的数互不相同。

\(f_{i,j}\) 表示长度为 \(i\),值域在 \([0,2^j)\) 之间的 \(\text{bad}\) 序列个数,发现这并不好转移。问题出在,比起关心一共有多少位,我们更关心的是有多少个位置的 \(\text{or}\) 和是 \(1\)

将状态改为 \(f_{i,j}\) 表示长度为 \(i\),所有数 \(\text{or}\) 起来的 \(\text{popcount}=j\) 的序列个数;\(All_{i,j}\) 表示 \(i\) 个值域在 \([0,2^j)\) 的数,它们按位或起来为 \(2^j-1\) 的方案数;\(g_{i,j}\) 表示在 \(All_{i,j}\) 的基础上,每个数互不相同的方案数。其中 \(All\)\(g\) 数组均可以通过经典的容斥求出。

枚举 \(a\) 表示最长 \(\text{good}\) 子序列的长度,\(b\) 表示这个 \(\text{good}\) 子序列按位或的 \(\text{popcount}\)。有转移:

\[f_{i,j}\gets \sum_{a=0}^{i-1}\sum_{b=0}^{j-1} (All_{a,b}-f_{a,b})\binom{i}{a}\binom{j}{b}2^{(i-a)b}g_{i-a,j-b} \]

其中 \(All_{a,b}-f_{a,b}\) 即为可能的合法序列个数;两个组合数分别决定 \(\text{good}\) 序列对应的位置和二进制位;\(2^{(i-a)b}\) 表示原序列剩下的位置有 \(b\) 个二进制位是随便选的,这样的数有 \((i-a)\) 个; \(g_{i-a,j-b}\) 满足上文「删不掉的序列的性质」。

时间复杂度 \(O(n^2k^2)\),不过这个人懒得预处理快速幂,多个 \(\log\) 也能过。

CF1637G Birthday

Tags: *3000, constructive algorithms, greedy, math.

对小数据打表,会发现一个神奇结论:最后这 \(n\) 个数都变成了第一个大于等于 \(n\)\(2\) 的正整数次幂。设这个数为 \(k\)
考虑对这个神奇现象作出解释。我们发现,对于除 \(2\) 以外的质数 \(p\),它是一个奇数。那么如果 \(x,y\) 中有一个 \(\bmod\ p\) 不为 \(0\),怎么操作都不能让它们为 \(0\)。那么最后的得数也就只能是 \(2\) 的幂了。

考虑构造答案。
发现如果序列里有 \(0\),倍增一个数的操作是容易构造的:\((0,x)\to (x,x)\to (0,2x)\)。也就是说我们只要搞出一个 \(0\),且剩下的数都是 \(2\) 的幂,就做完了。
首先贪心地将所有 \(i\)\(k-i\) 配对操作,我们发现序列分成了三部分:

  • \(1,2,\dots,x\),这一段因为太小而配不上对;
  • \(2,4,\dots,y\),这一段是所有配对得到的差;
  • 一个 \(\frac{k}{2}\),因为它也配不上对;
  • 若干个 \(k\),这是所有配对得到的和。

前两部分都是一个子问题,可以贪心地把它们继续配成若干 \(\frac{k}{2}\),再把剩下的配成 \(\frac{k}{4}\),以此类推。

具体地,我们维护两个集合 \(s,t\)\(s\) 表示要配对的集合,\(t\) 表示配对失败的集合。
每次从 \(s\) 中取出最大的数,检查它能否与集合内凑成 \(2^x\) 的形式,能则操作,不能则把它扔进 \(t\)。每次在 \(s\) 中加入操作产生的新数时,检查 \(t\) 里面有没有数因为这个新数而变得能配对,有则将该数移回 \(s\)
最后处理 \(t\) 里剩下的 \(0\),操作若干次 \((0,k)\) 即可。

[SDOI2017] 硬币游戏

Tags: NOI/NOI+/CTSC, probabilities, hashing

奇妙期望,实在是太厉害了!5 月的模拟赛搬过这个题,但当时还不会 ACAM 和高斯消元,于是不会写暴力,获得了 0pts 的好成绩。

首先有一个比较(也许并不)显然的暴力是在 ACAM 上跑高斯消元。问题出在这样的状态数是 \(nm\) 级别的,而这题似乎又难以避开高斯消元,时间复杂度完全不能承受。
我们的核心目标是减少未知量的数目。
发现一个重要的性质:对于任意一个非终止状态,我们不关心它的具体概率;换句话说我们可以把所有非终止状态都当成一样的。

但是这样有什么问题呢?
比如令 \(A=101,B=110\),一个非终止状态为 \(S\)
那么 \(S\) 在后面加上 \(A\) 就会结束,但也有可能中途结束。比如,当 \(S\)\(1\) 为结尾时,其实子串 \(B\)\(A\) 先出现。有如下情况:

\[S101=(S+A)+(S'+A+01)+(S''+B+1) \]

引理:构造出一个长度为 \(l\) 的特定 \(01\) 串的概率是 \(\frac{1}{2^l}\)
所以根据上式,我们可以写出:

\[\frac{1}{8}S=(1+\frac{1}{4}A)+\frac{1}{2}B \]

也就是说,若字符串 \(i\) 长度为 \(k\) 的后缀与 \(j\) 相同,\(i\)\(\frac{1}{2^{m-k}}\) 的概率提前结束。
这样我们构造出了 \(n\) 个关于 \(S\)\(n\) 个字符串的方程。在最后根据实际意义补上一个 \(\sum p_i=1\),凑够了 \(n+1\) 个方程,可以高斯消元。时间复杂度 \(\mathcal{O}(n^3)\)

[BalticOI 2014 Day1] Sequence

Tags: 省选/NOI−,数位分治

首先尝试构造一个答案的上界,容易发现当 \(N=102345678900000\) 时,无论给出什么样的数列都符合条件。也就是说,当一个数大于 \(16\) 位时不可能成为答案。

考虑枚举第一个数的最低位是什么。由此,我们可以推出所有位置最低位的值,并判断哪些已经满足了条件。
在这个基础上,忽略掉所有数的最后一位,那么以每 \(10\) 个数字分段,一段内的数字除最后一位外都相同。把它们的限制合并,当成一个数来看,问题规模缩小为原来的 \(\frac{1}{10}\)。递归计算即可。

对这个看起来很暴力的做法分析时间复杂度,根据主定理有 \(10T(\frac{n}{10})+\mathcal{O}(n)=\mathcal{O}(n \lg n)\)

实现上,注意前导 \(0\) 和进位的特判。

GF 集训 (2023.5) (22+0)/43

XDFZ 集训 (2023.7) (37+0)/66

  • 20
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值