如果你还 AK 不了 Atcoder Beginer Contest

前言

!?难难?!

\(\text{Balanced Subarrays}\)

\(\text{Part I-I}\)

对于第一问,每种颜色出现次数为定值 \(k\),考虑枚举右端点 \(r\),那么对于某一种颜色,设其当前出现序列为 \(p_1,p_2\dots p_t\)

那么对于其合法的左端点区间就为 \((p_t,r]\)\((p_{t-k},p_{t-k+1}]\),每次新增一个颜色对其的合法区间的改变是容易维护的。

我们需要对所有颜色对应的区间求交集大小,用线段树维护最大值及其个数即可,复杂度 \(O(n\log_2 n)\)

\(\text{Part I-II}\)

还有一种 \(\text{Hash}\) 做法。

考虑设 \(s_{i,j}\) 表示 \(1\sim i\) 中颜色 \(j\) 出现的次数,那么区间 \([l,r]\) 合法的一个必要条件是 \(\forall x,s_{r,x}\equiv s_{l-1,x} \pmod k\)

对于每个 \(i\),把 \(s_{i,j}\) 全部 \(\bmod k\),然后将 \(s_{i,1\sim n}\) 看作一个字符串 \(S_i\),则上述条件变为 \(S_r=S_{l-1}\),可以用字符串哈希判断。

进一步地,枚举 \(r\) 时双指针移动 \(l\),保证 \([l,r]\) 中任意颜色的出现次数均不超过 \(k\),然后每次查询与当前 \(r\) 相等的在区间内的字符串个数即可。

map 实现是 \(O(n\log_2 n)\),写个哈希表可以做到线性。

\(\text{Part II}\)

颜色种数为定值 \(k\)

考虑枚举右端点 \(r\),那么所有以 \(r\) 结尾的合法区间的颜色集合是一定的,同时我们可以得到可取的 \(l\) 的范围,使得范围内的 \(l\) 均满足 \([l,r]\)\(k\) 种颜色。

为每个颜色给定一个随机权值 \(w\),那么如果设合法区间颜色集合的总权值是 \(S\),那一个合法区间的权值和一定是 \(S\) 的倍数。

考虑用这个进行判断,预处理 \(f_i\) 表示 \(1 \sim i\) 前缀的权值和,则我们需要维护 \(f \bmod S\) 的值。

注意到若 \(S\) 为定值可以开个 map 直接维护。

每次添加一个数,当且仅当这个数不在当前颜色集合中时 \(S\) 才会发生变化,而 \(S\) 变化后所对应的合法 \(l\) 区间一定是不交的,故我们可以直接暴力清空 map 并重新赋值。

总复杂度 \(O(n\log_2 n)\)

\(\text{Random Subtraction}\)

考虑到最终的 \(x^2\) 可以表示为 \((a_1\pm a_2 \pm a_3 \pm\dots \pm a_n)^2\)

\(\sum_{i=1}^n a_i^2 + \sum_{i<j} \pm2a_ia_j\)

前一部分求和为定值,我们只需要考虑后一部分的期望值即可。

由于任意两个二元组本质没有区别,所以需要考虑的是对于原序列中某两个数最终同号或者异号的概率。

注意到两个数如果在某次操作中合并在一起,那么在后面的操作中就不会改变符号的异同。

那么直接枚举其合并在一起的时间,这样仅需考虑前若干次操作,两个数同号或异号的概率即可。

若当前序列长度为 \(len\),两个数未合并,则如果其中一个数被选作该次操作的 \(j\),同异号取反,否则不变。

则变号的概率为 \(p_{len}=\frac 2 {len}-\frac 2 {len(len-1)}\),注意这里要减去合并在一起的概率。

那么直接进行递推,设 \(f_i\) 表示 \(i\) 次操作后,两个数未合并且同号的概率,\(g_i\) 表示异号,则有:

\[f_i=p_{n-i+1}g_{i-1}+(1-p_{n-i+1}-\frac 2 {(n-i+1)(n-i)})f_{i-1} \]

\(g_i\) 的转移同理,时间复杂度 \(O(n)\)

\(\text{Many Repunit Sum 2}\)

考虑把可用的数字转化一下,设第 \(i\) 个数的位数为 \(d_i\),拼出来的数为 \(S\),则有:

\[\begin{aligned} S&=\sum_{i=1}^n \sum_{j=0}^{d_i-1} 10^j\\ &=\sum_{i=1}^n \frac {1-10^{d_i}}{1-10}\\ 9&S=\sum_{i=1}^n 10^{d_i}-1\\ 9&S+n=\sum_{i=1}^n 10^{d_i} \end{aligned} \]

问题转化为,用 \(10\)\(1\sim m\) 次幂,能凑出来多少个不同的 \(\geq 10n\) 的数。

为了方便描述,进一步转化为用 \(10\)\(0 \sim m-1\) 次幂,能凑出来多少个不同的 \(\geq n\) 的数。

直接枚举每个次幂用多少次会算重,比如 \(100+10 \times 1=11\times 10\),同样都用了 \(11\) 个数拼出 \(110\),但是拼的方式却不同。

\(c_i\) 表示 \(10^i\) 使用的次数,则我们需要考虑对每个数钦定一个唯一的 \(c\) 数组进行统计。

若数的从低向高的第 \(i\) 位是 \(x\),则我们钦定 \(c_{i-1}=x\),特别地,设其在第 \(m\) 位及其以后组成的多位数是 \(y\),则钦定 \(c_{m-1}=y\)

但是这样的钦定是对于这个数,花费最少的 \(10\) 的幂次的个数的钦定,也就是说 \(\sum_{i=0}^{m-1} c_i \leq n\)

注意到对于那些合法的数,其对应的 \(c\) 数组均满足 \(\sum_{i=0}^{m-1} c_i \equiv n \pmod 9\)

考虑算出和分别为 \(0\sim n\)\(c\) 数组的方案数,这是一个类似背包的问题,考虑生成函数,用 \(F(x)\) 表示答案的生成函数,则有:

\[F(x)=(\sum_{i=0}^9 x^i)^{m-1} (\sum_{i=0}^n x^i) \]

用多项式快速幂可以解决,但注意到底数的最高次只有 \(9\),所以可以直接递推,后面的乘法也可以用一些简单的方式处理,复杂度 \(O(n)\)

注意要减去 $0\sim n-1 $ 中产生贡献的数喵!

\(\text{Domino Arrangement}\)

\(\text{Part I}\)

\(f_{i,j}\) 表示前 \(i\) 个位置,第 \(i\) 个位置涂了颜色 \(j\) 的方案数,\(j=0\) 表示未涂色。

发现转移的形式是全局乘 \(-1\) 和全局加 \(\sum_{j=0}^m f_{i-2,j}\),涂色的区间限制是单点置 \(0\),可以用线段树直接维护,复杂度为 \(O(n\log_2 n)\)

\(\text{Part II}\)

由于最后只需要求 \(\sum_{j=0}^m f_{n,j}\),所以考虑直接维护每一位的和 \(s_i\)

令在当前位置 \(i\) 可以涂的颜色是已激活颜色,其个数为 \(cnt\)

那么 \(s_i\) 可以视作先加上 \(f_{i,0}+cnt \times s_{i-2}\),再减去 \(s_{i-2}\),但是这里会有一些小问题。

\(i-1\)\(i\) 被激活的颜色没有被减去:这没有影响,因为它们在 \(i-2\) 的值本来就是 \(0\)

\(i-1\)\(i\) “失活”的颜色不该被减去:考虑每个 \(f_{i,j}\) 的本质。

\[\begin{aligned} f_{i,j}&=s_{i-2}-f_{i-2,j}\\ &=s_{i-2}-s_{i-4}+f_{i-4,j}\\ &=s_{i-2}-s_{i-4}+s_{i-6}-f_{i-6,j}\\ &\cdots \end{aligned} \]

其本质上可以用 \(s\) 形式很简单地表示出来,考虑用前缀和维护这个东西,那么就可以 \(O(1)\) 求出某个特定的 \(f_{i,j}\)

对于在 \(i-1\)\(i\) “失活”的颜色,重新加上它们的贡献即可,时间复杂度 \(O(n)\)

\(\text{Keyboard}\)

容易想到的一个方向是对于每个数字求出一个界限 \(r\),表示若询问的右端点 \(>r\) 就会被删除。

那么回答询问只需要考虑那些 \(r>R\) 的数字。

但是由于带修,这个问题实际上完全强于动态求区间大于某个数的个数,所以我们考虑换个方向。

尝试用线段树去直接维护这个过程,设 \(s_i\) 表示区间的答案,\(l_i\) 表示区间最后剩下多少个数字,\(d_i\) 表示区间内有多少次在空串时进行了删除。

发现合并是容易的,只不过需要使用单侧递归的技巧。

时间复杂度为 \(O(n\log_2 n +q\log_2^2 n)\)

\(\text{One Time Swap 2}\)

考虑如何刻画交换后的字典序变化。

\(a_l>a_r\),则字典序变小,\(l\) 越小字典序越小,对于 \(l\) 相同的,\(a_r\) 越小字典序越小,如果 \(a_r\) 也相同,\(r\) 越大字典序越小。

对于 \(a_l<a_r\) 的情况同理,\(a_l=a_r\) 则字典序不变。

把所有询问按 \(k\) 从小到大离线,先正着扫一遍序列,处理所有字典序变小的部分,然后处理不变的,再倒着扫一遍处理字典序变大的部分即可。

这个过程可以简单地用主席树进行维护,时间复杂度 \(O(n\log_2 n)\)

\(\text{Takahashi's Expectation 2}\)

\(\text{Sum of Min of XOR}\)

先把所有的 \(a_i\)\(\text{Trie}\) 树。

\(\text{Part I}\)

\([0,m-1]\) 放在树上贪心地走,若有对应边则走,否则就走另一条边。

走到从下往上数第 \(d\) 层时,我们看作所有数只保留了低 \(d\) 位。

那么不难归纳出,某个节点上的数一定是覆盖了若干次整个区间,再加上某一段前缀的形式。

直接在 \(\text{dfs}\) 的过程中算出答案即可。

\(\text{Part II}\)

如果没有发现每个节点上的数的形式非常优雅,可以考虑若 \(m\)\(2\) 的若干次幂,其在树上走的过程将会很简单。

那么当 \(m\) 不是 \(2\) 的若干次幂时,可以用类似倍增的形式对其进行划分,每一部分都可以看作 \(m\)\(2\) 的若干次幂情形下的子问题。

\(\text{Part III}\)

考虑数位 \(\text{DP}\),设 \(f_{i,j}\) 表示高 \(i\) 位已经确定时,当前在 \(\text{Trie}\) 树上的节点编号为 \(j\),所有可能的数的贡献和。

转移直接枚举第 \(i\) 位是 \(0\) 还是 \(1\),根据树边的有无计算贡献即可。

这里的记忆化数组如果直接开是 \(O(n\log_2^2 V)\) 的,但是发现每个 \(j\) 对应的 \(i\) 是唯一的,所以第一维可以去掉,复杂度 \(O(n\log_2V)\)

posted @ 2026-06-25 14:30  jr_zch  阅读(16)  评论(2)    收藏  举报