CF dp + 计数做题记录

代码力量

dp + 计数的做题记录,由于都是一样的算法所以用时间顺序。

会进行时间的记录。

之前做的。

2026.5.28

Count Voting

思路:17mins14s

AC:1h3mins

想题 \(20mins\),调题 \(1h\)

我们发现一个组的人是等价的,所以我们把给个人的票数加到一个组里,使得 \(a_i\) 表示组 \(i\) 需要 \(a_i\) 个票,\(b_i\) 表示能给出多少票。

\(dp_{i, j, k}\) 表示到了第 \(i\) 个组后缺了 \(j\) 个票剩余了 \(k\) 个票,我们将其向 \(dp_{i + 1}\) 转移,枚举 \(x\) 表示用 \(x\) 个票去补前 \(j\) 个空,用 \(k\) 个中的 \(y\) 个来填 \(i + 1\) 的空,显然有:

\[dp_{i + 1, j - x + (a_{i + 1} - y), k - y + (b_{i + 1} - x)} \\ = dp_{i + 1, j - x + (a_{i + 1} - y), k - y + (b_{i + 1} - x)} + \binom{j}{x} \times \binom{b_{i+1}}{x} \times x! \times \binom{k}{y} \times \binom{a_{i+1}}{y} \times y! \times dp_{i, j, k} \]

直接做是 \(n ^ 4\) 会被卡常。我们注意到 \(k\) 可以算出来所以不用枚举优化到 \(n ^ 3\)。答案是 \(dp_{n, 0, 0} \times \prod_{i = 1} ^ n (c_i!)^{-1}\),因为我们把每个人获得的 \(c_i\) 张票当成了互不相同的不同空位。

code

2026.5.29

XOR Counting

思考:42mins28s

人类智慧题根本想不到。

\(m = 1\) 答案显然为 \(n\)

\(m \ge 3\) 时,我们注意到我们随便找两个位置放相等的数,剩下的数随便放,其异或和的奇偶性一定与 \(n\) 相同。所以 \(m >= 3\) 时答案就为所有 \(x \le n\)\(x \equiv n \pmod 2\),即为:

\[\begin{cases} \frac{(n + 1) ^ 2}4 \quad (n \equiv 1 \pmod 2) \\ \frac{n(n + 2)}{4} \quad (n \equiv 0 \pmod 2) \end{cases} \]

\(m = 2\) 时才需要正经算。\(dp_i\) 表示和为 \(i\) 的答案,\(f_i\) 表示和为 \(i\) 的方案数。当 \(i\) 为偶数,\(dp_i = 2 \times (dp_{\frac{i}{2}} + dp_{\frac{i}{2} - 1})\)\(f_i = f_{\frac{i}{2}} + f_{\frac{i}{2} - 1}\);当 \(i\) 为奇数,\(dp_i = 2 \times dp_{\frac{i}{2}} + f_{\frac{i}{2}}\)\(f_i = f_{\frac{i}{2}}\)

code

Wooden Spoon

AC:1h18mins

cf2400 都做这么久?抓紧重开咯。

我们注意到比赛是一个二叉树,我们令我们钦定的木勺奖获得者在左边,然后依次打右边的人,最后再将答案乘 \(2 ^ n\) 即可。这样我们就把原序列分成了 \(1 + 2 ^ 0 + 2 ^ 1 + \cdots 2 ^ {n - 1}\) 个段,每个 \(2 ^ k\) 的最小值小于 \(2 ^ {k - 1}\) 的最小值。直接计数不方便,考虑 \(dp\)。设 \(f_{i, j}\) 表示 \(i\) 充当 \(2 ^ j\) 的段的最小值且 \(2 ^ j\) 的段只填了 \(i\) 一个数一共把 \([1, i]\) 的数都填完了的方案数。起始情况显然为 \(f_{1, n - 1} = 2 ^ {n - 1}\)。转移也比较简单。由于长度 \(\le 2 ^ {j - 1}\) 的最小值都应大于 \(i\),那么小于 \(i\) 的数就只应该在比 \(2 ^ {j}\) 更大的段里出现。我们考虑枚举更小的 \(k\) 作为 \(2 ^ {j + 1}\) 的最小值,然后把 \([i + 1, k]\) 的数往上面的 \(2 ^ n - 2 \times 2 ^ j - k\) 个空隙中填,显然有转移:

\[f_{i, j} = \sum_k ^ {i - 1} \binom{2 ^ n - 2 \times 2 ^ j - k}{i - k + 1} \times (i - k + 1)! \times f_{k, j + 1} \]

拆开组合数显然有:

\[f_{i, j} = \sum_k \frac{(2 ^ n - 2 ^ {j + 1} - k)!(i - k + 1)!}{(2 ^ n - 2 ^ {j + 1} - i + 1)!(i - k + 1)!} \times f_{k, j + 1} \]

提出公因式并约分,得:

\[f_{i, j} = \frac{1}{(2 ^ n - 2 ^ {j + 1} - i + 1)!} \sum_k (2 ^ n - 2^{j + 1} - k)! f_{k, j + 1} \]

前缀和优化可做到 \(O(n 2 ^ n)\)。对于求答案,类似的,对于 \(i\) 枚举 \(k\) 并把剩下的 \(2 ^ n - k - 1\) 个数填进去,有:

\[ans_i = 2 ^ n \sum (2 ^ n - k - 1)! f_{k, 0} \]

做完了,前缀和优化即可。

code

2026.5.30

Card Guessing

思考:50mins45s

首先将答案摊到每次猜。对于第 \(i\) 张牌,只能看到当前大小为 \(m = \min(i-1, k)\) 的窗口。在给定窗口内四种花色的数量 \((a_1, a_2, a_3, a_4)\) 的情况下,如果某种花色在窗口中出现了 \(a_j\) 次,那么下一张牌属于该花色的概率恰好为:

\[\frac{n - a_j}{4n - m} \]

显然会猜牌的牌数为 \(\min(a_1, a_2, a_3, a_4)\),其剩余牌数为 \(n - \min(a_1, a_2, a_3, a_4)\),那么猜对的概率显然为:

\[\frac{n - \min(a_1, a_2, a_3, a_4)}{4n - m} \]

所以,对于固定的窗口大小 \(m\),猜对的概率期望为:

\[\sum_{\sum a_j = i, m = \min(i - 1, k)} \frac{\binom{n}{a_1}\binom{n}{a_2}\binom{n}{a_3}\binom{n}{a_4}}{\binom{4n}{m}} \cdot \frac{n - \min(a_1, a_2, a_3, a_4)}{4n - m} \]

这样的 \(n ^ 4\) 会 T。由于 \(\min(a_1, a_2, a_3, a_4) = \sum_{M=1}^{n} [\min(a_1, a_2, a_3, a_4) \ge M]\),我们可以计算 \(\min(a_1, a_2, a_3, a_4) \ge M\) 的贡献。\(dp_{i, j}\) 表示考虑完了 \(i\) 种颜色的贡献一共选了 \(j\) 张牌的贡献,\(F_i\) 表示 \(\sum_{\text{所有选 } i \text{ 张牌的方案}} \min(c_1, c_2, c_3, c_4)\) 张牌的方案数,我们枚举 \(M\),对于每一层 \(M\) 都进行一次背包,有:

\[dp_{0, 0} = 1 \quad dp_{i, j} = \sum_{M \le k \le n} \binom{n}{k} dp_{i - 1, j - k} \quad F_i = \sum_M dp_{4, i} \]

对于 \(F_i\),根据前面的式子,首先有 \(\sum (\binom{n}{a_1}\binom{n}{a_2}\binom{n}{a_3}\binom{n}{a_4}) (n - \min\{a\}) = n\binom{4n}{i} - F_i\),那么有答案:

\[ans = \sum_i (n \binom{4n}{m} - F_i) \frac{1}{(4n - m) \times \binom{4n}{m}} \]

其中 \(m = \min(k, i - 1)\)

code

2026.6.1

Maximum Element

AC:48mins6s

被诈骗了。

正难则反。设 \(dp_i\) 表示在前 \(i\) 个中找不到最大值的方案数。由于是排列我们不用管每个数具体的值,只需要管其大小关系(即于值域中的位置)。我们考虑容斥,那么 \(dp_i\) 总方案数应为从 \(i - 1\) 个数中再填一个数,有 \(i\) 个位置,即 \(i \times dp_{i - 1}\),然后容斥掉不合法的,首先有一个最大的在第 \(i\) 个,然后再在剩余 \(i - 1\) 个位置中选出 \(k\) 个位置任意顺序填 \([i - k + 1, i]\) 中的数,再乘上前面的 \(dp_{i - k - 1}\),这样子区间 \([i - k, i]\) 就会使得 \(a_{i - k}\) 被当成最大值。总结一下转移为:

\[dp_i = i \times dp_{i - 1} - dp_{i - k - 1} \times \binom{i - 1}{k} k! \]

然后对于算答案,我们枚举 \(n\) 的位置,假设为 \(i\),前面的方案数为 \(dp_{i - 1}\),后面的数随便填,显然有:

\[ans = n! - \sum_i \binom{n - 1}{n - i - 1} (n - i - 1)! dp_{i - 1} \]

做完了。

code

怎么题解区的做法全都和我不一样啊。

Triangles

思路:6mins5s

AC:10mins

打表 3 项加 oeis 得,设 \(ans\) 为:

\[\sum_i^{n / 2} 4 \prod_{j = 2} ^ i (2 ^ j - 3) \]

答案为:

\[2 ans ^ 2 + 8ans + 10 \]

code

Travel Plan

思考:34mins32s

基本想出来了,看了题解之后调了很久。

我们知道我们可以分别枚举路径长 \(l\) 和最大值 \(i\) 和长度为 \(l\) 的路径的数量假设为 \(c\),那么有显然的贡献:\((i ^ l - (i - 1) ^ l) \times i \times c \times m ^ {n - l}\),于是我们就需要 dp 求出每个 \(c\)

\(dp_{j, i}\) 表示 \(i\) 子树中到根路径包含 \(j\) 的点的路径数,\(dp_{j, i}\) 表示 \(i\) 子树中含 \(j\) 个点的路径的条数。我们发现若我们求出了一个 \(i \times 2\)\(i \times 2 + 1\) 的答案,那么转移到 \(i\) 是简单的,直接跟着定义转移即可。但是直接转移是 \(O(n \log ^ 2 n)\) 的,我们发现 \(\forall i\) 的子树中至少有一个为满二叉树,我们可以预先处理出满二叉树的 \(f\) 值,并且对于满二叉树显然有 \(dp_{j, i} = 2 ^ {j - 1}\),这样我们可以把我们的 dp 层数做到 \(\log n\) 层,直接预处理后 dfs 即可。

做完了,总时间复杂度 \(O(\log ^ 3 n + m \log n)\),注意后面算的时候要预处理幂。

具体细节看代码吧。

code

2026.6.2

Cards

思考:40mins20s

不会斯特林数啊,就说怎么做不出来,直接概率转计数然后一去不复返了。

这里介绍一种不是斯特林的方法。

我们注意到答案显然为 \(\sum_i \binom{n}{i} (\frac{1}{m}) ^ i (1 - \frac{1}{m}) ^ {n - i} i ^ k\),直接算 \(O(n)\) 会趋势。我们考虑组合意义,\(i ^ k\) 表示从 \(i\) 个物品中可重的选 \(k\) 个。

我们可以拆贡献。将 \(i ^ k\) 可以拆成 \(\sum_{j \le i} f(j, k)\),其中 \(f(j, k)\) 表示从 \(j\) 个中选 \(k\) 个且 \(j\) 个物品至少要被选到过一次的方案数。现在答案变成了 \(\sum_i P(i) \sum_{j \le i} f(j, k)\),继续拆贡献后等价于 \(\sum_j P(i \ge j) f(j, k)\),显然有 \(P(i \ge j) = \frac{1}{m ^ j}\),总结答案为:

\[\sum_j \frac{1}{m ^ j} f(j, k) \]

现在考虑 \(f(j, k)\) 怎么求。我们设 \(dp_{i, j}\) 表示长度为 \(i\) 的序列中出现了 \(j\) 个值且值域为 \([1, n]\) 的方案数,那么显然有 \(f(j, k) = dp_{k, j}\)\(dp\) 显然有 \(O(k ^ 2)\) 转移:

\[dp_{i, j \le i} = dp_{i - 1, j} \times j + dp_{i - 1, j - 1} \times (n - (j - 1)) \]

预处理 \(dp\) 然后枚举 \(j\) 直接算即可,注意到 \(j \le k\) 否则 \(f(j, k)\) 所对应的 \(dp_{k, j}\)\(0\),所以枚举 \(j\)\(O(k)\) 的。

做完了。

code

Crossword Expert

思路:34mins11s

AC:57mins36s

好慢,可能是因为最开始看到体面很长比较畏惧。

水。我的做法甚至不需要 dp,随随便便的双指针就写完了。

首先显然需要前缀和一下 \(t\) 记为 \(sum\)。首先我们设 \(f(i, j)\) 表示前 \(i\) 个数有 \(j\) 个加一的概率,显然有 \(f(i, j) = (\frac{1}{2}) ^ i \binom{i}{j}\)。设 \(ans_{i, j}\) 表示最终恰好做了 \(i\) 道题并有 \(j\) 个题时间加一(后面简称罚时),那么显然当 \(T = sum_{i + 1} + j\) 时,有 \(i + 1\) 吃罚时时 \(i\)\(j\) 才合法,其对答案的贡献为 \(\frac{1}{2}f(i, j) \times i\),这种情况枚举 \(i\) 直接加即可;对于 \(sum_i + j \le T\)\(T \le sum_{i + 1} + j - 1\)\(j\),化简得 \(j \in [T - sum_{i + 1} + 1, T - sum_{i}]\),显然有贡献 \(f(i, j) \times i\),我们发现 \(i\) 减小时 \(j\) 增大,且有 \(j \le i\),双指针暴力算即可(其实直接枚举也行,因为显然 \(\sum j \le n\))。

code

Fancy Arrays

思考:30mins5s

第一步转换都没想出来。。。。。。\ll\ll\ll\ll\ll

第一部转换,题目条件为 \(\min \{a_i\} \le x + k - 1\)\(\max \{a_i\} \ge x\)

考虑容斥,容斥成「\((\min \{a_i\} \le x + k - 1) - (\max \{a_i\} < x)\)」。第一种,由于非负,所以最小值有 \(x - k\) 中,每个差分数组的位置有 \(2 k + 1\) 中取值,所以总方案数为 \((x - k)(2 k + 1) ^ {n - 1}\);对于第二种,由于值域只有 \([0, x)\),设 \(dp_{i, j}\) 表示第 \(i\) 个数值为 \(j\) 的方案数,显然有 \(dp_{i, j} = \sum_{|j - l| \le k} dp_{i - 1, l}\),矩阵优化即可。

code

2026.6.3

Greg and Caves

思路:10mins26s

AC:45mins38s

\(dp_{i, j}\) 表示长度为 \(i\) 且最后一行(最宽的一行)宽度为 \(j\) 的方案数,显然有:

\[dp_{i, j} = 1 + \sum_{l = 2} ^ j dp_{i - 1, l} \times (j - k + 1) \]

注意到 \(dp_{i, j} - dp_{i, j - 1} = \sum_{l = 2} ^ j dp_{i - 1, l}\),前缀和优化可以优化到 \(O(n ^ 2)\)。算答案可以枚举最大值的位置和最大宽度,设在第 \(i\) 列去到最大长度 \(j\),显然有答案:

\[dp_{i, j} \times (dp_{n - i + 1, j} - dp_{n - i, j}) \times (m - j + 1) \]

\(dp_{n - i, j}\) 是因为减去有多个最大长度的段的重复计数。做完了。

code

Koxia and Tree

思考:31mins50s

状态拉完了,离正解就差一个把贡献拆到边,为什么没有想到呢。

我们钦定 \(1\) 为根,对于点 \(i\) 子树内有 \(siz_i\) 个蝴蝶。我们注意到,在经过蝴蝶飞来飞去之后,设子树内还有 \(siz ^ \prime _ i\) 个点,那么 \(|siz ^ \prime _ i - siz_i| \le 1\)。我们考虑将贡献拆到每条边。我们按顺序枚举边,设 \(p_i\) 表示第 \(i\) 个点有蝴蝶的概率,设边中父亲为 \(u\) 儿子为 \(v\),当 \(u\)\(v\) 上都有蝴蝶,显然 \(siz_v\) 一定不会变,这一块的贡献就为:

\[\frac{2}{k(k - 1)}(p_u \times p_v + (1 - p_u) \times (1 - p_v)) \times siz_v(k - siz_v) \]

对于 \(u\)\(v\) 没蝴蝶,有 \(\frac{1}{2}\) 的概率 \(siz_v\) 加一,所以有贡献:

\[\frac{2}{k(k - 1)}(p_u \times (1 - p_v)) \times \frac{1}{2}(siz_v(k - siz_v) + (siz_v + 1)(k - siz_v - 1)) \]

对于 \(v\)\(u\) 没有,类比一下显然有:

\[\frac{2}{k(k - 1)}(p_v \times (1 - p_u)) \times \frac{1}{2}(siz_v(k - siz_v) + (siz_v - 1)(k - siz_v + 1)) \]

然后对 \(p\) 进行转移,显然有:

\[p_u = p_v = \frac{p_u + p_v}{2} \]

做完了。

code

Crypto Lights

思路:24mins53s

AC:31mins53s

做的最快的 2600,和之前绿的 2500 有的一拼。

考虑拆贡献。设 \(f(i)\) 表示至少能开 \(i\) 个灯的概率。由于是至少,答案应该为 \(1 + \sum_{i = 1} ^ n f(i) \times 1\)。现在考虑求 \(f(i)\),若要在 \(n\) 个点中选出 \(i\) 个位置每个相隔至少 \(k - 1\),根据插板法其方案数应为 \(\binom{n - (i - 1)(k - 1)}{i}\),那么 \(f(i)\) 就显然为:

\[\binom{n - (i - 1)(k - 1)}{i} i! \frac{(n - i)!}{n!} \]

做完了。

code

Omega Numbers

思考:53mins

不会莫反没办法。

直接求肯定没法求,显然是要对乘积的 \(\omega\) 等一一个数的数进行计数。直接计不好记,但我们注意到 \(\omega_{\max} \le 6\),且有 \(\omega(a_i \times a_j) = \omega(a_i) + \omega(a_j) - \omega(\gcd(a_i, a_j))\)。我们设 \(dp_{i, j}\) 表示 \(\omega(a_x) + \omega(a_y) = j\)\(\gcd (a_x, a_y) = i\)\((x, y)\) 有序点对(包括 \(x = y\))个数,那么答案显然为 \(\sum_i \sum_j (j - \omega(i)) ^ k\)。直接算 \(dp\) 数组,我们不妨设 \(f_{i, j}\) 表示 \(i \mid a_x\)\(i \mid a_y\)\(\omega(a_x) + \omega(a_y) = j\)\((x, y)\) 个数,显然,有:

\[f_{i, j} = \sum_{d \mid i} dp_{d, j} \]

我们发现 \(f\) 是好算的,我们只需开一个 \(cnt_{i, j}\) 表示 \(i \mid a_x\)\(\omega(a_x) = j\)\(x\) 的个数,对于每一个 \(cnt_i\) 进行一下加法卷积就是 \(f_i\)。那么我们有了 \(f\) 要求 \(dp\),根据莫比乌斯反演,有:

\[dp_{d, j} = \sum_{d \mid i} \mu(\frac{i}{d}) f_{i, j} \]

做完了。注意要去重,因为直接算出来的答案中 \((x, y)\) 是有序点对且有可能 \(x = y\)

code

2026.6.4

Binary String Wowee

思路:29mins16s

AC:1h7mins46s

用时较久,瓶颈在组合数一直弄错了。

我们注意到前面的不管怎么弄都不会影响到后面的,但后面会影响到前面,于是我们设 \(dp_{i, j}\) 表示前 \(i\) 个换完还要换 \(j\) 次,转移我们考虑 \(i\) 这个位置换了 \(l\) 次。当 \(a_i = 0\) 时,第一次换之前后面大于 \(i\) 的位置应换偶数次,第 \(2\)\(l\) 次换中间后面的位置应换了奇数次,为了方便统计我们直接将最前面加上 \(1\) 这样我们就认为第一次之前后面的位置也要换奇数次,运用插板法显然有 \(\binom{\lfloor \frac{j + l + 1}{2} \rfloor}{l} dp_{i - 1, j + l}\);当 \(a_i = 1\),我们可以认为先消耗了一次把 \(a_i\) 换成了 \(0\),类比可想出转移。总结一下:

\[dp_{i, j} = \sum_l \binom{\lfloor \frac{j + l + 1 - a_i}{2} \rfloor}{l} dp_{i - 1, j + l} \]

做完了,答案为 \(dp_{n, 0}\)

code

Electrical Efficiency

思考:25mins27s

没看标签所以想不到虚树,看到是虚树就秒了。

拆贡献到每个边和每个质数,对于每个质数建一个虚树做完了。

code

Team Work

思考:31mins2s

不会斯特林数就狂推是吧。。。二项式定理做力竭了。。真得找时间学一下斯特林数了。

将原题看作 \(n\) 个箱子选出 \(i\) 个箱子装入 \(k\) 个球。答案为:

\[\sum_{i = 1} ^ k S(k, i) \binom{n}{i} i! 2 ^ {n - i} \]

这里 \(\binom{n}{i} i!\) 等价于 \(\frac{n!}{(n - i)!}\) 可以直接算。

code

Jumping Man

思考:约 30mins

???看错题了想了 inf 年。

考虑将题目限制转化为相等的字符串个数,那么设 \(dp_{i, j}\) 表示 \(i\) 为起点和 \(j\) 为起点的相等的字符串,当 \(s_i \ne s_j\) 时显然为 \(0\),否则有转移:

\[dp_{i, j} = 1 + \sum_{x \in sub_i} \sum_{y \in sub_j} dp_{x, y} \]

其中 \(sub_i\)\(sub_j\) 分别表示 \(i\)\(j\) 的不包含本身的子树的点集。注意到转移顺序是 dfs 序逆序,对 dfs 序二维后缀和优化可以做到 \(O(n ^ 2)\)。答案也比较好算,对于点 \(i\) 答案为:

\[\sum_{x \in sub_i \lor x = i} \sum_{y \in sub_i \lor y = i} dp_{x, y} \]

显然还是可以二维前缀或后缀和优化。做完了。

code

2026.6.5

Emotional Fishermen

思路:28mins12s

AC:1h11mins0s

细节有点多所以调了比较久。

先对 \(a\) 从小到大排序,并预处理出 \(pre_i\) 表示最后一个 \(a_j \times 2 \le a_i\)\(j\) 若没有为 \(0\)\(suf_i\) 表示第一个 \(j\) 使得 \(a_i \times 2 \le a_j\) 若没有则为 \(n + 1\)。设 \(dp_i\) 表示前缀最大值为 \(a_i\) 的方案数,注意到正着不好 dp 我们倒着做,并把 dp 状态精确一下,\(dp_i\) 表示最大值为 \(i\)\([a_{pre_i + 1}, a_n]\) 都已经填完了的方案数,这么设计的原因是区间 \((pre_i, n]\) 的数在最大值为 \(a_i\) 的段是不合法的,应该把这些插到最大值为 \(\ge 2 \times a_i\) 的段。根据定义,显然初始状态为 \(dp_n = [pre_n = n - 1]\),有转移:

\[dp_i = \sum_{j = suf_i} ^ {n} dp_j \times \binom{(n - pre_j - 1) + (pre_j - pre_i - 1)}{pre_j - pre_i - 1} (pre_j - pre_i - 1) ! \]

这么转移,是因为要把 \((pre_i, pre_j]\) 不包含 \(i\)\(pre_j - pre_i - 1\) 个数插到最大值 \(\ge a_j\) 的区间中,于是显然能得出这个转移。对于算答案,假设 \(i\) 作为第一个数,那么显然有贡献:

\[\binom{n - 1 + pre_i}{pre_i} pre_i! \times dp_i \]

其中 \(\binom{n - 1 + pre_i}{pre_i} pre_i!\) 表示把 \([1, pre_i]\) 的数插到 \(i\) 后面的 \(n - 1\) 个位置的方案数。

做完了。

观察到转移的这个形式可以优化到 \(O(n)\) 的转移,推式子提取公因数并用前缀和优化即可。

code

Conditional Mix

思考:36mins46s

撒比性质题。这篇写得好。

code

2026.6.7

6767676767676767!!!

Club of Young Aircraft Builders (easy version)

思路:4mins46s

AC:25mins52s

犯糖了所以 T 了一发。

\(dp_{i, j}\) 表示 \([i, n]\) 的楼层一共射了 \(j\) 发,枚举第 \(i\) 层射了 \(k\) 发,显然有:

\[dp_{i, j} = \sum_{k = 0} ^ c \binom{c}{k} dp_{i + 1, j - k} \]

做完了。

code

Club of Young Aircraft Builders (hard version)

思考:1h1mins5s

2900 确实不好做,但做法理解起来也不难。

和简单版不太一样。直接做显然不好做,我们考虑转化。我们发现第一个人肯定于 \([1, c]\),我们将第 \(i\) 个人所丢的飞机统称为 \(i\),把所有 \(1\) 去掉,那么 \(2\) 就肯定于 \([1, c]\)。我们不难发现规律,对于 \(i\),把 \([1, i - 1]\) 全部去掉,那么 \(i\) 肯定于 \([1, c]\),也就是说假如 \([1, i - 1]\)\(x\) 个,那么 \(i\) 一定于 \([1, x + c]\)。我们注意到这样可以 dp,我们设 \(dp_{i, j}\) 表示 \([1, i]\) 一共丢了 \(j\) 个,我们设 \(i\) 位于 \([1, r]\),我们枚举 \(i\) 丢了 \(k\) 个,那么根据上面的结论有 \(r = c + j - k\)。对于判断不可能,设 \(p = \max_{a_t = i}\{t\}\),当 \(p > r\) 时显然不可能。对于转移,假设 \([1, r]\) 的指定的位置中,有 \(a\) 个位置已经被指定了大于等于 \(i\) 的数,而 \(b\) 个位置指定了 \(i\),显然把 \(i\) 填进去就有 \(\binom{r - (j - k) - a}{k - b} = \binom{c - a}{k - b}\) 种方案,总结一下有转移:

\[dp_{i, j} = \sum_{k \le \min(j, c)} \binom{c - a}{k - b} dp_{i - 1, j - k} \]

\(a\)\(b\) 可以通过二维前缀和快速求出。做完了。

code

2026.6.9

Igor and Interesting Numbers

思考:26mins42s

状态不好所以差一步,其实这道题并不难。

下面为了方便叙述把题目中的 \(k\) 换成了 \(n\)。数据很小我们可以使用十分暴力的方法做。我们注意到应先求出数字有多少位,我们从低到高枚举,假设我们枚举到有 \(len\) 位,设 \(dp_{i, j}\) 表示前 \(i\) 个数字填了 \(j\) 个,我们用 \([1, 16]\) 来表示 16 进制下的 \([0, f]\),由于 \(0\) 不能于最前面,显然有初始状态 \(dp_{1, i} = \binom{len - 1}{i}\)。对于转移,不难发现枚举 \(i\) 填了 \(k\) 个有:

\[dp_{i, j} = \sum_{k \le \min(j, t)} \binom{len - (j - k)}{k} dp_{i - 1, j - k} \]

那么 \(i\) 位答案就为 \(dp_{16, len}\),方便表示我们设其为 \(f\),那么若 \(f \ge n\) 说明 \(len\) 就是正确的;否则将 \(n\) 减去 \(f\) 继续枚举 \(len + 1\)。枚举完位数我们从高到低枚举每一位的数,注意第 \(len\) 位应从 \(2\) 开始枚举而其他位可以从 \(1\) 开始,因为显然最高位不能为 \(0\)。设 \(lim_x\) 表示 \(x\) 还可以用多少次,假设我们第 \(i\) 位枚举到了 \(j\),那么我们设第 \(i\) 位枚举到了 \(j\) 的方案数为 \(f\),如果 \(f \ge n\) 说明第 \(i\) 位就是 \(j\),将 \(lim_j\)\(1\) 然后枚举下一位即可;否则我们将 \(n\) 减去 \(f\) 继续枚举 \(j + 1\)。现在考虑怎么求 \(f\),我们可以类似的 dp,设 \(dp_{i, j}\) 表示前 \(i\) 个数填了 \(j\) 个的方案数,显然有 \(f = dp_{16, len}\),其中 \(len\) 表示枚举到的位数,由于没有最高位不为 \(0\) 的限制显然有初始状态 \(dp_{0, 0} = 1\),显然有类似的转移:

\[dp_{i, j} = \sum_{k \le \min(j, lim_i)} \binom{len - (j - k)}{k} dp_{i - 1, j - k} \]

做完了。

code

The Top Scorer

思考:1h

重开吧。被容斥弄死了。

注意到当 \(r = 0\) 时答案为 \(\frac{1}{n}\),当 \(r > 0\),假设 \(1\) 在内有 \(x\) 个数 \(\le r\),那么概率为 \(\frac{1}{x}\)。显然我们可以容斥成大于等于 \(x\) 个并转成计数,显然有答案:

\[\frac{1}{\binom{s - r + p - 1}{p - 1}} \sum_{x = 1} (-1) ^ {x + 1} \frac{1}{x} \binom{p - 1}{x - 1} \binom{s - x \times r + p - x}{p - x} \]

做完了。

code

2026.6.10

Pairs of Paths

思考:32mins56s

这其实是一道纯数据结构题。于是没有做出来。

我们钦定 \(1\) 为根,我们注意到答案的贡献一定有两种:交点为四个点共同的 lca,交点不为共同的 lca。首先对于 \((u, v)\) 的路径,我们先求出 lca 为 \(l\),设其为 \(u\)\(k\) 级祖先,那么设 \(a\)\(u\)\(k - 1\) 级祖先,\(b\)\(v\) 同理。特别的,若 \(u\)\(v\) 的祖先,那么钦定 \(a\)\(0\) 即不存在,若 \(u = v\)\(a = b = 0\)

先考虑交点为 \(lca\)。开三个桶,\({buc_0}_l\) 表示 lca 为 \(l\) 的路径,\({buc_1}_{l, x}\) 表示 lca 为 \(l\)\(a\)\(b\) 有一个为 \(x\)\({buc_2}_{l, x, y}\) 表示 lca 为 \(l\)\(a\)\(b\) 分别为 \(x\)\(y\)。我们对于每一个路径一个一个算,假如现在算到了 \((l, a, b)\),贡献显然为 \({buc_0}_l - {buc_1}_{l, a} - {buc_1}_{l, b} + {buc_2}_{l, a, b}\),然后把对应的值都加一,记得特判 \(a\)\(b\)\(0\) 的情况。

对于第二种,我们考虑枚举 \(l\) 的深度,假设我们现在路径为 \((l, a, b)\),设 \(sum_i\) 表示 \(i\) 子树中的公共祖先深度比 \(l\) 的深度小的路径端点个数,那么 \((l, a, b)\) 的贡献显然为 \(sum_l - sum_a - sum_b\)。注意到可以用 dfs 序加上树状数组维护,位置 \(i\) 维护 dfs 序为 \(i\) 的端点的个数。那么设 \(x\) 的 dfs 序为 \(in_x\)\(x\) 的子树中 dfs 序最大为 \(out_x\),显然有 \(sum_x = [in_x, out_x]\),其中 \([in_x, out_x]\) 表示树状数组这个区间内的值。对于每一个深度,先算贡献,然后对于每一个 \(u\)\(v\) 的地方贡献加 \(1\)

把两个部分贡献加起来就做完了。具体细节可以看代码。

code

Bash Plays with Functions

思路:32mins47s

AC:1.5h

啥子卡常题,\(2.4 \times 10 ^ 8\) 过不了 \(3\) s??????????

没有观察到 \(f_r(n)\) 的极性,直接做的。首先显然,\(f_0 (x) = 2 ^ {\omega(x)}\)。我们注意到其实 \(f_r(n) = \sum_{d \mid n} f_{r - 1} (d)\)。这样还是不好算,我们可以考虑 \(f_0 (d)\)\(f_r (n)\) 的贡献。假设 \(d \times x = n\),我们要算 \(d\) 对于 \(n\) 的贡献,我就是求 \(d \times \prod_{i = 1} ^ r a_i = n\)\(a\) 的方案数,显然有 \(x = \prod_{i = 1} ^ r a_i\),方案数显然可以通过对 \(x\) 的每个质因数插板法得出,设 \(x = \prod_i p_i ^ {k_i}\),那么 \(d\) 显然有贡献:

\[f_0 (d) \times \prod_i \binom{k_i + r - 1}{r - 1} \]

暴力的找出每一个 \(d\) 然后算即可,需要亿点卡常就过啦,理论最多算 \(q \times 240\) 次,其具体方法可以看代码。

code

Copy or Prefix Sum

思路:18mins32s

AC:58mins36s

上一道题红温导致调了很久。

显然可以想到 dp,设 \(dp_{i, j}\) 表示前 \(i\) 个和为 \(j\) 的方案数,对于 \(b_i = a_i\) 显然有 \(dp_{i, j} = dp_{i - 1, j - a_i}\);对于 \(b_i = \sum_{j = 1} ^ i a_j\) 显然为 \(dp_{i, a_i} = \sum_{j \le R} dp_{i - 1, j} - dp_{i - 1, 0}\),注意到转移正好契合线段树的区间平移、单点修改和区间求和,离散化的线段树维护即可。

注意要离散化,动态开点 MLE。

code

2026.6.11

Expected Destruction

思考:30mins58s

严肃不会。

我们把集合中的 \(i\) 定义为「在 \(i\) 位置的球」,我们把操作 3 没有发生称为两个球融合了。我们注意到,如果没有发生融合,那么答案显然为 \(\sum_{i = 1} ^ n (m - a_i + 1)\),如果发生融合位置于 \(x\),那么总贡献将减少 \(m + 1 - x\)。我们把融合都看成相邻球发生的,于是我们可以枚举 \(i\)\(i\)\(i + 1\) 融合的位置的期望。设 \(dp_{j, k}\) 表示 \(i\) 走到 \(j\)\(i + 1\) 走到 \(k\) 的概率,显然有 \(dp_{a_i, a_i + 1} = 1\),当 \(j = k\) 对答案显然有贡献 \(-dp_{j, k} \times (m + 1 - j)\)。我们考虑转移,由于选取是随机的,如果我们只看 \(i\)\(i + 1\) 两个球,那么 \(i\) 向前走一步的概率和 \(i + 1\) 向前走一步的概率都为 \(\frac 1 2\),那么 \(j \ne k\) 时对于 \(dp_{j + 1, k}\)\(dp_{j, k + 1}\) 的贡献为:

\[\frac 1 2 \times dp_{j, k} \]

做完了,复杂度 \(O(n m ^ 2)\)

code

DSU Master

思路:1h3mins12s

AC:1h45mins22s

大水题做这么久,我真菜。

显然当 \(a_1 = 1\) 答案为 \(0\)。对于 \(a_0 = 0\),我们考虑拆贡献到每个 \(a_i = 0\)。假设 \(dp_i\) 表示长度为 \(i\) 的段 \(i \leftarrow i + 1\) 的贡献,显然 \(a_i = 1\)\(dp_i\)\(0\),我们发现排列中只有 \([1, i)\) 只有在 \(i\) 之前出现才有贡献。设 \(f_i\) 表示 \([1, i]\) 作为前缀的合法排列,对于 \(a_i = 0\) 随便找个位置放即可,否则 \(i\) 不能放在最后一个,因为若放在最后一个,\(1\)\(i\) 联通,会产生一条 \(1 \rightarrow i + 1\) 的边使后面都无法产生贡献。总结一下,有:

\[\begin{cases} dp_i = f_{i - 1} \quad (a_i = 0)\\ dp_i = 0 \quad (a_i = 1) \end{cases} \\ \begin{cases} f_i = f_{i - 1} \times i \quad (a_i = 0) \\ f_i = f_{i - 1} \times (i - 1) \quad (a_i = 1) \end{cases} \]

对于算答案,设 \(ans_i\) 表示长度为 \(i\) 的答案,贡献分两类。一是确定 \(i\) 要产生贡献,就为 \(dp_i\);二不管 \(i\) 有没有贡献,那么 \(i\) 随便放,贡献为 \(ans_{i - 1} \times i\),总结一下贡献为:

\[ans_i = ans_{i - 1} \times i + dp_i \]

做完了。

code

Greedy Grid Counting

思考:53mins10s

AC:1h29mins41s

麻烦。可能是我头昏完了做了很久。

我们对于原网格的任意宽度为 \(2\) 的子网格,我们化简成这样:

i y a c
x b d e

其中 \(i\)\(x\)\(y\)\(e\) 皆表示一个点的值,且令 \(i\) 表示 \(a_{1, i}\),而另外几个表示一个区间的值。我们分类,当 \(x \le y\) 时答案显然不劣;当 \(x > y\),设 \(b ^ \prime = x + b\)\(a ^ \prime = y + a\),仅当 \(b ^ \prime \ge a ^ \prime\) 时成立,即 \(x - y \ge a - b\),设 \(dp_{i, j}\) 表示 \(i\) 合法且 \((a ^ \prime - b ^ \prime)_{\max} = j\) 的方案数,显然 \(i + 1\)\(a ^ \prime\) 对于 \(i\) 来说就是 \(a\),初始状态有 \(dp_{n, 0} = 1\),我们枚举 \(d = x - y\)\(cnt\) 表示合法的 \((x, y)\) 使得 \(d = x - y\) 成立的方案数,我们注意到其实 \(j \ge k\)\(j = k\) 再转移上等价,\(j \le 0\)\(j = 0\) 同理,所以说第二维其实也只有 \(k\)。那么根据定义,有转移:

\[dp_{i, \min(k, \max(0, j - d))} = dp_{i, \min(k, \max(0, j - d))} + dp_{i + 1, j} \times cnt \]

\(a_{1, 1}\)\(a_{2, n}\) 对答案没有影响可以随便填。做完了。

code

Diameter Cuts

思路:11mins48s

AC:1h36s

好耶是简单题。

\(dp_{x, j}\) 表示 \(x\) 不与父亲连时最大深度为 \(j\)合法方案数,\(f_x\) 表示其不与父亲连的时候的合法方案数,跟着定义有 \(f_x = \sum_j dp_{x, j}\)。方便计数我们设我们 dp 到了第 \(x\) 个点,设 \(pre_{i, j}\) 表示前 \(i\) 个儿子最大深度深度小于等于 \(j\) 的方案数,\(suf_{i, j}\) 为后缀同理,这个比较好求。接下来我们来求 \(dp\) 数组,当 \(dp_{x, j}\)\(j\) 满足 \(2j \le k\),很好办,设 \(x\)\(m\) 个儿子,则 \(dp_{x, 0} = pre_{m, 0}\)\(dp_{x, j} = pre_{m, j} - pre_{m, j - 1}\)。当 \(2j > k\) 时,枚举儿子 \(i\) 是唯一一个深度为 \(j\) 的,那么有:

\[dp_{x, j} = \sum_i pre_{i - 1, k - j} \times suf_{i + 1, k - j} \times dp_{i, j - 1} \]

做完了。注意由于会 MLE,可以将 \(suf\) 滚动数组并跟着 \(2j > k\) 的循环一起算。

code

2026.6.12

Ksenia and Combinatorics

思考:40mins17s

AC:1h34mins51s

最开始看成最大独立集了。。

简单的 dp。设 \(dp_{i, j, 0 / 1}\) 表示大小为 \(i\) 的子树,匹配为 \(j\),根是否被匹配的方案数。为了方便不去重,我们介绍一种钦定的方式,我们钦定 \(dp_{i, j, 0/1}\) 增加两条限制,根的排列最小,排列次小值在左子树,这样就规避了左右子树一样需要去重。这个钦定大概就是这个题的精华了,想到这个就做完了,利用贪心能想到转移:

\[\begin{cases} dp_{i, j, 0} = \sum_{x + y = i - 1} \sum_{a + b = j} dp_{x, a, 1} \times dp_{y, b, 1} \times g(x, y) \\ dp_{i, j, 1} = \sum_{x + y = i - 1} \sum_{a + b = j} g(x, y) \times (dp_{x, a, 1} \times dp_{y, b - 1, 0} + dp_{x, a, 0} \times dp_{y, b - 1, 0} + dp_{x, a, 0} \times dp_{y, b - 1, 1}) \end{cases} \]

这里的 \(g(x, y)\) 表示把大小为 \(x\)\(y\) 的子树去掉根排列最小的限制,且使 \(x\) 作为左子树并使 \(x\)\(y\) 中最小值在 \(x\) 内的方案数,不难发现,其等于:

\[\binom{y + x - 1}{x - 1} \times x \times y \]

做完了。

code

Mighty Rock Tower

思考:1h。

看错题想了 46mins。

显然是 \(dp\)。我们注意到设 \(dp_i\) 表示到第 \(i\) 层期望个数不好算,考虑差分,设 \(dp_i\) 表示 \(i - 1 \rightarrow i\) 期望个数。首先至少放一个,有 \(1\) 的贡献,有 \({p_i} ^ j\) 的概率会掉到 \(i + 1 - j\) 层以下,有 \(dp_{i + 1 - j}\) 的贡献。我们可以得到:

\[dp_i = 1 + \sum_{j = 1} ^ i {p_i} ^ j dp_{i + 1 - j} \]

\(dp_i\) 提出来移项,再化系数为 \(1\),的得:

\[dp_i = \frac{1 + \sum_{j = 2} ^ {i} {p_i} ^ j dp_{i + 1 - j}}{1 - p_i} \]

对于每一个 \(p_i\) 开一个前缀和维护 \(\sum_{j = 2} ^ {i} {p_i} ^ j dp_{i + 1 - j}\),由于 \(p_i\) 只有 \(100\) 种取值,所以复杂度为 \(O(n \times 100)\)

做完了。

code

2026.6.15

Bacterial Melee

思路:39mins39s

AC:48mins18s

666 最开始想的做法假了。

直接计数不好计,考虑转化。我们注意到,我们设形成的字符串为 \(s\),给的字符串为 \(t\),那么 \(s\) 有可以表示为 \(t_{a_1} \times k_1 + t_{a_2} \times k_2 + \cdots + t_{a_m} \times k_m\),其中 \(m \le n\)\(\sum_{i = 1} ^ m k_i = n\)\(1 \le a_1 < a_2 < \cdots < a_{m - 1} < a_m \le n\),且对于任意 \(i < m\) 显然应有 \(t_{a_i} \ne t_{a_{i + 1}}\),加号表示字符串拼接。我们发现,如果我们固定了 \(m\)\(a\),那么 \(k\) 的方案数是固定的,插板法有 \(\binom{n - 1}{m - 1}\)。我们考虑 dp,设 \(dp_i\) 表示 \(i = m\)\(a\) 数组的方案数,答案应为:

\[\sum_{i = 1} ^ n \binom{n - 1}{i - 1} dp_i \]

现在考虑怎么转移。假如枚举到了第 \(i\) 个位置要算 \(dp_j\),直观的 \(dp_j = dp_{j - 1}\),但是这样会计多次。我们考虑开成两维方便计数,\(dp_{i, j}\) 表示前 \(i\) 个数确定了 \(j\) 个数,设 \(lst_i\) 表示上一个和 \(i\) 的字符相同的位置,我们发现必须从 \(lst_i\) 之后的状态转移,否则会和 \(lst_i\) 的状态重复,于是转移应为:

\[dp_{i, j} = \sum_{k = lst_i + 1} ^ {i - 1} dp_{k, j - 1} \]

用滚动数组和前缀和优化可以做到 \(O(n ^ 2)\)。做完了。

code

Counting Is Not Fun (Easy Version)

思路:15mins

AC:30mins

手滑把计时器重启了所以时间为大概时间。

简单题。我们首先注意到,对于一个大括号里直接包含的空格,假设有 \(x\),设 \(f(x)\)\(x\) 个空格的方案数,列出递推式子后不难发现这是个卡特兰数,显然有:

\[f(x) = \begin{cases} 0 \quad (x \equiv 1 \pmod 2) \\ C_{\frac{x}2} \quad (x \equiv 0 \pmod 2 \wedge x \ne 0) \\ 1 \quad (x = 0) \end{cases} \]

其中 \(C_x\) 表示卡特兰数第 \(x\) 项。我们只需要倒序删好对子,设前括号为 \(1\) 后括号为 \(-1\) 空格子为 \(0\),每次删只需要将 \(a_l\)\(a_r\) 都赋值成 \(0\),然后对于每一个还存在的好对子的区间算 \(f(x)\) 乘起来,用栈维护即可。做完了。

code

Counting Is Not Fun (Hard Version)

思路:4mins36s

AC:24mins7s

简单题。

沿用上一问的思路。假设我们要删一个好对子为 \([l, r]\),他被直接包含于 \([a, b]\),设 \(siz_l\) 表示 \([l, r]\) 直接包含的空格数,那么只需要先 \(ans \leftarrow \frac{ans}{f(siz_l) \times f(siz_a)}\),然后 \(siz_a \leftarrow siz_l + siz_a + 2\),最后 \(ans \leftarrow ans \times f(siz_a)\) 即可。所以我们现在只需要删掉每个 \([l, r]\) 时快速找到其 \([a, b]\) 就行。我们注意到包含关系是一个棵树,并且 \([a, b]\)\([l, r]\) 没有被删掉的最近祖先,可以用并查集维护,做完了。具体细节看代码。

code

Mercenaries

思考:38mins40s

不太会解决第一个限制。

看到 \(m \le 20\) 不妨想到枚举包含限制的情况并且容斥。\(s \in [0, 2 ^ m)\)\(d\) 位表示第 \(d + 1\) 条冲突是否一定发生。对于每一个 \(s\),我们枚举冲突中的每个人,设 \(L = \max_{i \in s}\{l_i\}\)\(R = \min_{i \in s}\{r_i\}\),显然 \(L > R\)\(dp_{s} = 0\)。现在我们考虑怎么求 \(L \le R\) 的情况。我们设 \(cnt_i\) 表示 \(i \in [l_k, r_k]\)\(k\) 的个数,差分是好求的。设 \(f_{i, j} = \sum_{k = 0} ^ i \binom{cnt_k - j}{k - j}\),其中 \(\binom{cnt_k - j}{k - j}\) 表示选 \(k\) 个人,其中有 \(j\) 个被限制人必须选的方案数,\(f_{i, j}\) 显然为第一维的前缀和。那么对于 \(dp_s\) 的范围为 \([L, R]\),就应为:

\[f_{R, k} - f_{L - 1, k} \]

其中 \(k\) 为冲突中包含的人数。注意到这里 \(dp_s\) 为「至少」,我们应容斥到「恰好」,由于我们 \(s\) 的状态是二进制压缩的,直接 FWT 与的逆运算即可。做完了。

code

2026.6.16

Subsequences Galore

思路:13mins30s

AC:52mins27s

熔池题。

我们设 \(A_i\) 表示 \(s_i\) 包含的子字符串序列数量,那么要求的其实就是每一个 \(|A_1 \cup A_2 \cup A_3 \cup \cdots \cup A_k|\)。交是不好算的,与的计算是显然的,即对于 \(|A_1 \cap A_2 \cap \cdots \cap A_k|\) 是好算的,只需找到每个字符在所有 \(s_{i}\) 最小出现次数加 \(1\) 乘起来,我们考虑容斥过去。根据容斥的公式,有:

\[|A_1 \cup A_2 \cup A_3 \cup \cdots \cup A_k| = \\ \sum |A_i| - \sum |A_i \cap A_j| + \cdots + (-1) ^ {k - 1} |A_1 \cap A_2 \cap \cdots \cap A_k| \\ =\sum_m \sum_{t} (-1) ^ {m + 1} |A_{t_1} \cap A_{t_2} \cap \cdots \cap A_{t_m}| \]

直接做即可,可以用高维前缀和,也可以给每一个赋上奇偶性贡献后 FWT。做完了,时间复杂度 \(O(26 \times n 2 ^ n)\)

code

Counting Prefixes

思考:1h12mins8s

口胡了差不多的做法。

构式题不想补。

Gifts

思路:23mins43s

AC:42mins46s

好耶ヽ(✿゚▽゚)ノ是简单题。

我们设所有名字的礼物中价值第 \(n\) 大的价值为 \(v\),那么大于 \(v\) 的必选,等于 \(v\) 的有概率选。考虑 dp,设 \(dp_{i, j}\) 表示第 \(i\) 个名字选完之后选出了 \(j\) 大于等于 \(v\) 个的概率,显然初始状态有 \(dp_{0, 0} = 1\),答案为 \(\frac{dp_{m, n}}{\binom{c_0}{n - c_1}}\),其中 \(c_0\) 表示等于 \(v\) 的个数,\(c_1\) 表示大于 \(v\) 的个数,除以 \(\binom{c_0}{n - c_1}\) 是因为每种等于 \(v\) 的都可能被选。现在考虑转移,设第 \(i\) 个名字等于 \(v\)\(cnt_0\) 个,大于的有 \(cnt_1\) 个,一共有 \(sz\) 个,根据定义有转移:

\[dp_{i, j} = \sum_{k = cnt_1} ^ {cnt_0 + cnt_1} \frac{dp_{i - 1, j - k}}{\binom{sz}{k}} \]

其中 \(\binom{sz}{k}\) 为选到 \(k\) 的概率。注意预处理时应用杨辉三角推组合数并且组合数数组开 double 才不会 RE。做完了。

code

Beautiful Bracket Sequence (easy version)

思路:25mins55s

AC:44mins47s

最开始又读错题了。/ll

我们考虑答案最大时,由于我们可以随便删,那么取到最大情况一定有 ((())),即删成这种只有嵌套括号的形式,且由于要最大所以括号要尽量多,由于要合法所以前后括号数要相等。于是我们可以 dp,设 \(dp_{i, j, 0 / 1}\) 表示第 \(i\) 个位置前缀有 \(j\)( 的情况数且 \(i\) 是否为 (\(f_{i, j, 0 / 1}\) 一样只不过是后缀 ),根据定义有简单的转移。(其实直接组合算也可以,不过做的时候范糖了只想到 dp。)我们可以拆贡献到每一个如 ((????)) 最右边的 ( 和最左边的 ),设位置分别为 \(l\)\(r\),我们再设 \(sum_{i}\) 为前 \(i\) 个中有多少 ?,那么答案应为:

\[\sum_k \sum_{l = 1} ^ {n - 1} \sum_{r = l + 1} ^ n dp_{l, k, 1} \times f_{l, k, 1} \times 2 ^ {sum_{r - 1} - sum_l} \\ = \sum_k \sum_{r = 1} ^ n dp_{l, k, 1} \times 2 ^ {sum_{r - 1}} \sum_{l = 1} ^ {r - 1} f_{l, k, 1} \times 2 ^ {- sum_l} \]

对后面枚举 \(l\) 的部分前缀和优化可做到 \(O(n ^ 2)\)。做完了。

code

Beautiful Bracket Sequence (hard version)

思路:34mins26s

AC:1h1mins4s

第一道自己做的 2900 捏。

书接 eazy version。我们对于答案式子:

\[\sum_k \sum_{r = 1} ^ n dp_{l, k, 1} \times 2 ^ {sum_{r - 1}} \sum_{l = 1} ^ {r - 1} f_{l, k, 1} \times 2 ^ {- sum_l} \\ = \sum_{r = 1} ^ n \sum_k dp_{l, k, 1} \times 2 ^ {sum_{r - 1}} \sum_{l = 1} ^ {r - 1} f_{l, k, 1} \times 2 ^ {- sum_l} \]

我们发现是在对每个 \(r\) 拆贡献,我们注意到,当位置 \(r\) 及其右边的 ) 加入个数为 \(a\)\(r\) 右边的 ( 个数为 \(b\),当 \(b \ge a\) 时一定有一个右端点为 \(r\) 的有贡献的括号。我们假设 \(r\) 右边有 \(y\) 个问号,钦定 \(r\) 不管是 ) 还是问好都是问号都是 ),设 \(r\) 及右边的 ) 个数为 \(b\),左边的 ?\(x\) 个,(\(a\) 个,那么我们的问题等价于:求 \(i + a \ge j + b\)\(i \le x\)\(j \le y\) 的非负整数解数。移向,得:

\[i - j \ge b - a \]

\(j = M - k\),得:

\[i - (M - k) \ge b - a \]

即:

\[i + k \ge b - a + M \]

答案显然为:

\[\sum_{s = b - a + M} ^ {x + y} \binom{x + y}{s} \]

注意到 \(x + y\) 只有两种取值,分别做前缀和优化就做完了。

code

2026.6.17

Typical Party in Dorm

AC:?

边看 wc 边做的,没计时。

询问比较大但 \(n\) 只有 \(1000\) 考虑预处理。直观的可以想到统计每个子字符串的贡献,设字符串 \([l, r]\) 必须要的字符集合为 \(s\),有 \(cnt\) 个自由元,其中自由元表示无论放什么数 \([l, r]\) 都为回文的 ? 个数。那么假设给定的字符集合就为 \(s\),那么这个串的贡献显然就为 \(popcount(s) ^ {cnt}\),但是事实是对于 \(\forall t \supseteq s\) 来说 \([l, r]\) 都有贡献,直接 dp 不好计,我们设 \(dp_{i, t}\) 表示假如 \(popcount(t)\)\(i\) 且给的集合为 \(t\) 的方案数。那么对于每一个 \([l, r]\),对于所有 \(p \ge popcoutn(s)\) 求出 \([l, r]\) 对其的贡献,即:

\[dp_{p \ge popcount(s), s} \leftarrow dp_{p \ge popcount(s), s} + p ^ {cnt} \]

对于所有字串都弄过一遍后,得到的 dp 数组并不是真正的 dp 数组,再对于每一个 \(dp_i\) 高维前缀和或 FWT 才能得出真正的 dp 数组。那么对于给定一个 \(t\),其答案就应为 \(dp_{popcount(t), t}\)。做完了。

code

Bingo

思考:40mins25s

5mins 想出了 \(n ^ 2 \times 2 ^ n\) 的 FWT 做法但没能想出进一步优化。

正难则反,我们考虑容斥,求出没有一个能够 bingo 的概率。我们考虑枚举每个列的情况和对角线的情况,设 \(t\) 表示两个对角线哪些 bingo,\(s\) 哪些列是否 bingo,两者都可以状压实现。设 \(F(t, s)\) 为在这些限制下每一行都没有 bingo 的概率,根据容斥,有:

\[\sum_t \sum_s -1 ^ {(|t| + |s|)} F(t, s) \]

现在我们来考虑怎么求 \(F(t, s)\)。对于每一行,我们设 \(dp_{i, m}\) 表式第 \(i\) 行中,属于 \(\forall k \in m\) 列的点发生的概率(\(m\) 的实现用状压),其可以递推求解做到 \(O(n 2 ^ n)\)。那么对于限制 \(s\)\(t\),我们显然是可以 \(O(1)\) 的算出第 \(i\) 行必须要发生的点集的,设其为 \(m_i\),那么 \(F(t, s)\) 就应为:

\[\prod_{i = 1} ^ n (dp_{i, m_i} - f_i) \]

做完了。

code

Ela Goes Hiking

思路:20mins37s

AC:48mins30s

没有特判 \(n = 1\) 所以调了有点久。

这是一道画图手模题。先转概率为计数。对于点 \(i\),我们发现如果 \(i = n\),那么向左向右等价;若 \(i \ge n\) 向右必死,于是我们只用考虑向左的情况即可。考虑若 \(i\) 存活,那么当 \(i\) 转到向右时他左边的显然都死光了,那么我们设向右为 0 左为 1,那么对于 ... 1 0 0 i,设其左边的最右边的 1 位置为 \(j\),那么我们发现若 \(i\) 向左,除了吃掉 1 右边的 0 使得其重量变为 \(i - j\),还会吃一个重量为 \(j\) 的,所以说如果 i 要活所以说 \(j \le i - j\),那么我们发现对于 \(i\)\((\lfloor \frac{i}{2} \rfloor, i)\) 必向右,再左边的无所谓,方案数为 \(2 ^ {\lfloor \frac{i}{2} \rfloor}\)。考虑左边,我们设左边为 i 0 0 1 0 0 1 0 0 0 1,设一串 0 0 0 0 1 为一段,第 \(i\) 段长度为 \(a_i\),那么有 \(i + \sum_{k = 1} ^ {\forall j} a_i > a_{j + 1}\),我们可以 dp 出方案数,设 \(dp_i\) 表示 \(i\) 右边的答案,那么显然有:

\[dp_i = \sum_{j = i + 1} ^ {i \le j - i} dp_j \]

所以对于每一个数,\(i = 1\) 时概率为 \(0\),否则概率为:

\[\frac{1}{2 ^ {n - 1}} \times 2 ^ {\lfloor \frac{i}{2} \rfloor} \times dp_i \]

其中除以 \(2 ^ {n - 1}\) 因为最右边的向左向右等价。做完了。

code

2026.6.18

New Year Garland

思考:1h30mins

草泥马的模数不是质数。

补几把。卡常卡空间不让用逆元。浪费生命。

code by Gemini.

Positions in Permutations

思路:32mins

AC:1h10mins43s

二反简单题,但有点忘了二反了。

看到恰好 \(k\) 直觉想到二反容斥成至少 \(k\),等价于钦定 \(k\) 个然后其他随便。观察下面的图:

无标题

我们设上面的求球为数字,下面的块为位置,排列中数字在一个位置两者连边,那么只有红色边是会产生贡献的。剩下的就简单了,dp 去记选的红边个数,设 \(dp_{i, j, 0/1, 0/1}\) 表示前 \(i\) 个块和球,钦定了 \(j\) 条红边,第 \(i\) 个球(数字)和块(位置)是否已经练连了红边,显然有转移:

\[\begin{cases} dp_{i, j, 0, 0} = dp_{i - 1, j, 0 / 1, 0 / 1} \\ dp_{i, j, 0, 1} = dp_{i - 1, j, 0, 0 / 1} \\ dp_{i, j, 1, 0} = dp_{i - 1, j, 0 / 1, 0} \\ dp_{i, j, 1, 1} = dp_{i - 1, j - 2, 0, 0} \\ \end{cases}\]

\(g_i\) 设一共钦定了 \(i\) 条红边其他随便选的方案数,显然其为 \(dp_{n, i, 0/1, 0/1}\),然后对 \(g\) 二反即可。做完了。

code

Eleventh Birthday

思路:?

AC:4h20mins

哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈小学知识不过关hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh。

首先要知道有一个小学性质,一个数能被 \(11\) 整除那么其奇数位和减偶数位和能被 \(11\) 整除,于是我们把数字化成两个信息,奇偶和的差 \(a_i\) 和数字长度奇偶性 \(t\),奇数为 \(1\) 偶数反之。我们发现对于每一个 \(t = 1\) 假设一共 \(sz\) 会把序列分成 \(sz + 1\) 段,一些段数字贡献为 \(x \times 1\) 一些为 \(x \times -1\),于是我们设 \(dp_{i, j, s}\) 表示前 \(i\)\(t = 0\) 的数有 \(j\) 个贡献为 \(1\)\(i - j\) 个贡献为 \(-1\) 且和对 \(11\) 取模后的方案数,那么有转移:

\[dp_{i, j, M(x + a_i)} \leftarrow dp_{i, j, M(x + a_i)} + dp_{i - 1, j - 1, x} \times (n_1 + j - 1) \\ dp_{i, j, M(x - a_i)} \leftarrow dp_{i, j, M(x - a_i)} + dp_{i - 1, j, x} \times (i - 1 - j + n_2) \]

其中 \(M(x)\) 表示 \(x\)\(11\) 取模,\(n_1 = \lceil \frac{sz + 1}{2} \rceil\) 表示贡献为 \(1\) 的段数 \(n_2 = \lfloor \frac{sz + 1}{2} \rfloor\) 反之。那么这就是 \(t = 0\) 部分的答案。考虑 \(t = 1\),设 \(f_{i, j, p}\) 表示前 \(i\) 个贡献为 \(1\) 的有 \(j\) 个,那么显然有 \(j \le k = \lceil \frac{sz}{2} \rceil\),那么有转移:

\[f_{i, j, p} = f_{i - 1, j, p} + f_{i - 1, j - 1, M(p - a_i)} \times (k - j + 1) \]

为了方便计数,设 \(g_x = \sum_i \sum_j dp_{i, j, x}\),那么有:

\[ans = \sum_{x + y \equiv 0 \pmod {11}} g_x \times f_{sz, k, y} \times (sz - k)! \]

做完了,具体细节看代码。

code

2026.6.22

Blossom

AC:?

看 wc 不计时。

考虑拆贡献,拆到每一个 \(mex \ge i\) 的区间都有 \(1\) 的贡献。我们设 \(dp_{i, j}\) 表示 \(mex \ge i\) 且区间中有 \(j\) 个自由元的区间数,我们设 \(tot\) 表示一共的自由元数,\(cnt\) 表示 \([0, i - 1]\) 有哪些数没出现过即自由元,那么答案显然为:

\[\sum_j \sum_i \binom{j}{cnt} cnt! (tot - cnt)! \sum_{k = i} ^ n dp_{k, j} \]

可以用前缀和优化 \(\sum_k dp_{k, j}\) 做到 \(O(n ^ 2)\),现在考虑怎么算 \(dp\) 数组。我们可以暴力枚举枚举区间 \([l, r]\),那么 \(mex\) 最大就为 \(\min_{\forall i \notin [l, r]} \{a_i\}\),设 \(sum_i\) 表示 \([1, i]\) 自由元个数,那么显然有:

\[dp_{\min_{\forall i \notin [l, r]} \{a_i\}, sum_r - sum_{l - 1}} \leftarrow dp_{\min_{\forall i \notin [l, r]} \{a_i\}, sum_r - sum_{l - 1}} + 1 \]

做完了。

code

AND Segments

思考:1h11mins54s

容斥想的有点问题。

首先对于限制进行二进制拆位,限制就变成了区间全部为 \(1\) 或不全部为 \(1\),而且显然对于区间全不为 \(1\) 的限制 \([a, b]\)\([c, d]\),若 \(c \le a\)\(d \ge b\) 可直接略掉 \([c, d]\)。具体做法我们考虑 dp,\(dp_i\) 表示位置 \(i\)\(0\) 的方案数,若 \(i\) 有区间全为 \(1\) 的限制那么 \(dp_i = 0\),否则显然 \(dp_i = \sum_{j = L} ^ {i - 1} dp_j\),其中 \(L = \max_{[l, r] \land r < i} \{r\}\),前缀和维护即可。

code

One-X

AC:1h

qwqwqwqwqwq

\(f(i, x)\) 表示长度为 \(i\) 顶点为 \(x\),那么贡献为 \(f(i, x) = f(i - \lfloor \frac{i}{2} \rfloor, 2x) + f(\lfloor \frac{i}{2} \rfloor, 2x + 1) + x \times g(\lfloor \frac{i}{2} \rfloor, i - \lfloor \frac{i}{2} \rfloor)\),其中 \(g(x, y) = (2 ^ x - 1) \times (2 ^ y - 1)\)。直接算不好算,于是我们把 \(x\) 拆开,得:

\[f(i, x) \\ = 2 f(i - \lfloor \frac{i}{2} \rfloor, 1) \times x + 2 f(\lfloor \frac{i}{2} \rfloor, 1) \times x + f(\lfloor \frac{i}{2} \rfloor, 1) + x \times g(\lfloor \frac{i}{2} \rfloor, i - \lfloor \frac{i}{2} \rfloor) \\ \]

把带 \(x\) 提出来分开递推即可,由于 \(x = 1\) 所以可以省掉一维。做完了。

code

2026.6.24

Chain Prefix Rank (Hard Version)

AC:2h

大战 2900 的 dp(s) 题。为什么题解区又没有我的做法?

平衡树 + 虚树。对于节点 \(u\),它的所有祖先中只有 \(a_u\) 个比它小。如果我们把当前路径上的所有祖先按照排列权值 \(p\) 从小到大排序,那么显然 \(u\) 应该恰好被插入到第 \(a_u + 1\) 个位置,那么在所有比 \(u\) 小的祖先中,权值最大的那一个是排在第 \(a_u\) 位的节点。我们称这个第 \(a_u\) 个点为 \(u\) 在值依赖树上的直接父亲(若 \(a_u = 0\),则其父亲为虚拟根节点 \(0\),比如 \(1\)),可以通过 dfs 的时候用 fhqtreap 做到 \(O(n \log n)\)。现在求出了值依赖树,对于一个节点 \(i\),它的所有直接儿子集合为 \(v_i\),那么我们发现对于所有 \(x \in v_i\) 的顺序是不固定的,我们现在对每个 \(v_i\) 中的点顺序计数即可。观察其约束,我们发现约束只有若 \(i\)\(j\) 的祖先,那么 \(i\) 应排在 \(j\) 后面。于是我们可以将每一个 \(v_i\) 拉出一个虚树,在虚树上直接计数即可,设 \(siz_{to}\) 表示点 \(to\)\(\sum_{l \in sub(to)} v_l\) 中的点数加上,其中 \(sub(x)\) 表示 \(x\) 虚树上的子树,那么对于点 \(x\) 来说,对答案的贡献就应为:

\[\frac{(\sum_{to \in sub(x)} siz_{to})!}{\prod_{to \in sub(x)} siz(to)!} \]

这是一个多重集排列数,把给个点的贡献乘起来就是最终答案。做完了,具体细节见代码。

code

Chain Prefix Rank (Easy Version)

AC:0s

做了 hard version 直接交过来了。

同上。

code

Permutation Blackhole

思考:28mins22s

不会。

考虑区间 dp。设 \(dp_{l, r, x, y}\) 表示当 \(l - 1\)\(r + 1\) 填好之后填完 \([l, r]\)\(l - 1\) 贡献了 \(x\)\(r + 1\) 贡献了 \(y\) 区间方案数,设 \(f(l, r, p)\) 表示 \([l, r]\) 最先填 \(p\) 会贡献到的位置,显然只有 \(l - 1\)\(r + 1\) 两种取值。根据定义,显然有 \(dp_{i + 1, i, 0, 0} = 1\)\(dp_{i, i, [f(i, i, i) == i - 1], [f(i, i, i) == i + 1]} = 1\) 的初始状态,\(dp_{1, n, 1, 0}\) 即为答案。对于转移,枚举最先填的点 \(k\),我们分成两类。当 \(s_k = -1\),那么应有:

\[dp_{l, r, x, y} \leftarrow dp_{l, r, x, y} + \binom{r - l}{k - l} \times \sum_i dp_{l, k - 1, x - [f(l, r, k) = l - 1], i} \times \sum_i dp_{k + 1, r, i, y - [f(l, r, k) = r + 1]} \]

对于 \(s_k \ne -1\),有:

\[dp_{l, r, x, y} \leftarrow dp_{l, r, x, y} + \sum_i \binom{r - l}{k - l} \times dp_{l, k - 1, x - [f(l, r, k) = l - 1], i} \times dp_{k + 1, r, s_k - i, y - [f(l, r, k) = r + 1]} \]

直接做看起来像 \(O(n ^ 6)\),但对于 \(x\)\(y\) 的两维,我们发现当 \(p\) 一个点 \(t\) 有贡献,那么 \([p, t]\) 中再填一个对 \(t\) 有贡献的数,其位置应该在 \([p, t]\) 的右半部分,我们发现其区间进行了减半,换句话说 \(x\)\(y\) 最多只有 \(\log n\),所以时间复杂度其实为 \(O(n ^ 3 \times \log ^ 3 n)\)。做完了。

code

Ehab and the Expected GCD Problem

思考:24mins2s

AC:38mins8s

注意力题。

为了使我们的不同 gcd 最多,设 \(p_1 = \prod_i p_i ^ {k_i}\) 我们考虑使 \(p_1\)\(\sum_i k_i\) 最多,然后每次最多减一个质因子,然后 gcd 的个数就是 \(\sum_i k_i\)。为了使 \(\sum k_i\) 最大,那么 \(p_1 = 2 ^ {\log n}\)\(2 ^ {\log n - 1} \times 3 ^ 1\)。设 \(dp_{i, j, k}\) 表示前 \(i\) 个数 gcd 为 \(2 ^ j \times 2 ^ k\) 的方案数,设 \(cnt(x, y)\) 表示 \(2 ^ x \times 3 ^ y\)\([1, n]\) 的倍数个数,那么显然有转移:

\[dp_{i, j, k} = (cnt(j, k) - i + 1) dp_{i - 1, j, k} + (cnt(j, k) - cnt(j + 1, k)) dp_{i - 1, j + 1, k} + (cnt(j, k) - cnt(j, k + 1)) dp_{i - 1, j, k + 1} \]

做完了,答案为 \(dp_{n, 0, 0}\)

code

2026.6.25

Balanced Domino Placements

思考:15mins21s

AC:1h9mins38s

是个鬼的 2600 啊。

我们发现对于多米诺牌只有 \(1 \times 2\)\(2 \times 1\) 两种,我们可以枚举两种各自的数量。我们设 \(cntr\) 是没有被钦定的行数,\(cntc\) 是没有被钦定的列数,设 \(f_i\) 表示从行中选出 \(i\) 个连续两个行都是没有被钦定的的方案数即 \(i\)\(1 \times 2\) 只考虑行的方案数,\(g_i\) 同理,通过计数每个 \(1 \times 2\)\(2 \times 1\) 所在行和列所在位置,那么显然有答案:

\[\sum_x \sum_y f_x \times g_y \times \binom{cntr - 2x}{y} y! \times \binom{cntc = 2y}{x} x! \]

现在考虑 \(f\)\(g\) 的求法,其求法显然是一样的,只用想出 \(f\) 的求法即可。设 \(dp_{i, j, 0 / 1}\) 表示前 \(i\) 行选出了 \(j\) 个位置且 \(i\) 有没有被钦定,\(a_i\) 表示第 \(i\) 行是否被钦定,显然有 \(f_i = dp_{n, i, 0} + dp_{n, i, 1}\),转移也是简单的:

\[\begin{cases} dp_{i, j, 0} = dp_{i - 1, j, 0} + dp_{i - 1, j, 1} \quad dp_{i, j, 1} = dp_{i - 1, j - 1, 0} \quad (a_i = 0) \\ dp_{i, j, 0} = 0 \quad dp_{i, j, 1} = dp_{i - 1, j, 1} + dp_{i - 1, j, 0} \quad (a_i = 1) \end{cases} \]

做完了。

code

Set

思考:1h

有难度的思维题,看了题解才会做。

我们考虑分治,类似 FWT,拆到每一位来看。首先定义 \(v_i\),我们重新定义其第 \(j\) 位为再多 \(j\)\(1\) 是否合法,假设 \(i ^ \prime\)\(i\) 多一个 \(1\) 那么显然有 \(v_{i ^ \prime} = \lfloor \frac{v_i}{2} \rfloor\)。我们设 \(a\)\(b\) 的第 \(k\) 位一下全部相同,第 \(k\) 位不同,其中 \(a\)\(k\) 位为 \(0\),考虑了第 \(k\) 位以下的限制分别为 \(v_a\)\(v_b\)。现在我们要加上第 \(k\) 位的限制,首先对于 \(v_a\) 若考虑第 \(k\) 层,那么直接 \(v_a \leftarrow v_a \And v_b\) 即可,而对于 \(b\) 来说第 \(k\) 位为 \(1\),所以对于 \(b\) 与上这一位为 \(1\) 的数会多出一个 \(1\),那么应有转移 \(v_b \leftarrow v_a \And \lfloor \frac{v_b}{2} \rfloor\),类似 FWT 的思路。把每一位都限制完之后,所有的满足 \(v_s \And 1 = 1\) 的状态都应是合法的。

做完了,记得将 \(v_0\) 手动赋值一个 \(1\)

code

Bags with Balls

思考:45mins23s

我尼玛又是斯特林推式子。

题结巴。

code

Minibuses on Venus (hard version)

思考:1h

666 原来是组合推式子。

首先 \(k = 1\)\(n = 1\) 情况答案显然为 \(1\)。关于其他情况,我们容斥,我们知道应存在 \(2x \equiv S\),我们只需要计数不包含 \(x\) 使得同余方程成立的序列个数即可。这样应分两种情况。当 \(k \equiv 1 \pmod 2\) 时,对于 \(\forall S\) 有唯一存在 \(x\),我们容斥,设 \(f(i)\) 表示包含了 \(i\)\(x\) 且和为 \(S\) 的方案数,当 \(i = n\) 时显有 \(f(n) = [n \times x \equiv S]\),其他时候则有:

\[f(i) = \binom{n}{i} k ^ {n - i - 1} \]

因为要保证和为 \(S\) 所以自由元个数为 \(n - i - 1\),对于答案 \(S\),容斥有:

\[\sum_0 ^ {n - 1} (-1) ^ i f(i) = \sum_0 ^ {n - 1} (-1) ^ i \binom{n}{i} k ^ {n - i - 1} + (-1) ^ n \times f(n) \]

利用二项式定理推前面部分:

\[\sum_0 ^ {n - 1} (-1) ^ i \binom{n}{i} k ^ {n - i - 1} + (-1) ^ n \times f(n) \]

\[= \frac{1}{k} \sum_0 ^ {n - 1} (-1) ^ i \binom{n}{i} k ^ {n - i} + (-1) ^ n \times f(n) \]

\[= \frac{1}{k} ((k - 1) ^ n - (-1) ^ n \binom{n}{n} k ^ 0) + (-1) ^ n \times f(n) \]

\[= \frac{1}{k} ((k - 1) ^ n - (-1) ^ n) + (-1) ^ n \times f(n) \]

\[= \frac{1}{k} ((k - 1) ^ n - (-1) ^ n) + (-1) ^ n \times [n \times x \equiv S] \]

把所有 \(S\) 答案加起来,对于 \(i = n\) 的贡献,有:

\[\sum_{S = 0} ^ {k - 1} (-1) ^ n [n \times x \equiv S] = (-1) ^ n \gcd(k, n - 2) \]

所以总不合法方案数为:

\[k \times \frac{1}{k} ((k - 1) ^ n - (-1) ^ n) + (-1) ^ n \gcd(k, n - 2) \]

\[= (k - 1) ^ n - (-1) ^ n + (-1) ^ n \gcd(k, n - 2) \]

答案即为:

\[k ^ n - (k - 1) ^ n - (-1) ^ n + (-1) ^ n \gcd(k, n - 2) \]

现在来考虑 \(k\) 为偶数。我们注意到 \(S \equiv 2x\) 这次有 \(2\) 个根,我们类似容斥,不包含这两个根,那么对于 \(f(i)\) 表示有 \(i\) 个位置为 \(x_1\)\(x_2\) 且和为 \(S\) 应有:

\[\binom{n}{i} s ^ i k ^ {n - i - 1} \]

对于一个特定的 \(S\) 有答案:

\[\sum_{i = 0} ^ {n - 1} (-1) ^ i \binom{n}{i} s ^ i k ^ {n - i - 1} + (-1) ^ n f(n) \]

\[= \frac{1}{k} ((k - 2) ^ n - (-2) ^ n) + (-1) ^ n f(n) \]

我们注意到 \(S\) 为奇时无解,那么把所有偶数 \(S\) 的贡献加起来有:

\[F = \frac{k}{2} \times \frac{1}{k} ((k - 2) ^ n - (-2) ^ n) + (-1) ^ n \sum f(n) \]

\[= \frac{1}{2} ((k - 2) ^ n - (-2) ^ n) + (-1) ^ n 2 ^ {n - 1} \gcd(n - 2, \frac{k}{2}) \]

那么有答案:

\[k ^ n - \frac{k ^ n}{2} - F \]

\[= \frac{1}{2} \left( k^n - (k-2)^n + (-2)^n \right) \mathbf{-} (-1)^n 2^{n-1} \gcd(n-2, \frac{k}{2}) \]

做完了。

code

2026.6.26

Friends and Pizza

思考:1h

以为是容斥结果是子集卷积。

我们注意到对于不能吃奇数个的限制,设所有奇数个的集合为 \(S\),那么第三个限制可以转化为 \(A \cap B \cap T = \empty\),显然有 \(|A \cap T| + |B \cap T| = |A \cap T \cap B \cap T|\),类似子集卷积直接做即可。

code

Destroy the Colony

思路:28mins1s

AC:1h6mins13s

好久没做过回退背包了。

\(dp_i\) 表示放了 \(i\) 个格子的方案数,\(n\) 表示字符串一半的长度,用 \([1, 52]\) 表示每个字符 \(a_i\) 表示第 \(i\) 个的个数,那么对于不加限制的方案数为 \(dp_n \times \frac{n!n!}{\prod_i a_i !}\)。显然 \(dp\) 用背包是好求的,那么对于给定的 \(u\)\(v\),设 \(f_{i}\) 表示填 \(i\) 个且不用 \(u\)\(v\) 的方案数,那么有答案:

\[f_{n - a_u - a_v} \times 2 \times \frac{n!n!}{\prod_i a_i !} \]

\(f\) 直接回退背包即可。由于 \((u, v)\) 的个数只有 \(52 \times 52\) 个,把询问离线下来是 \(52 \times 52 \times n\) 的。做完了,具体细节看代码。

code

2..3...4.... Wonderful! Wonderful!

思路:14mins56s

AC:1h13mins27s

怎么这么久。

枚举 \(k\)\(cnt\),其中 \(cnt\) 为删除次数,我们对于每一个 \(cnt\) 计数。对于 \(cnt = 0\) 显然只有一种,\(cnt = 1\)\(k\) 个和后 \(k\) 个之间至少隔一个有 \(\binom{n - 1}{2k}\)。对于其他情况,我们正难则反,总方案数减去不合法方案数。总方案数显有 \(\binom{n}{2 * cnt * k}\),不和法的构造方法为除了前 \(k - 1\) 个和后 \(k - 1\) 个全部连续,有方案数 \(\binom{n - 2(cnt - 1)k - 1}{2k - 1}\),总结为:

\[\binom{n}{2 * cnt * k} - \binom{n - 2(cnt - 1)k - 1}{2k - 1} \]

做完了,复杂度 \(O(n \ln n)\)

code

Chaotic Merge

AC:37mins27s

简单。

考虑 \(dp_{i, j, 0 / 1}\) 表示串 \(x\) 截止到第 \(i\) 个字符 \(y\) 到第 \(j\) 个字符最后一个是 \(x\)\(y\) 的字符的方案数,对于初始状况,我们预处理出所有形如 a .. a bb b .. b a 的情况,其中 ab 分别表示属于 \(x\)\(y\) 的字符,我们设 \(lst_{x / y, i}\)\(x\)\(y\) 上的第 \(i\) 个字符前最后一个 \(j\) 使得 \(x_j = x_{j - 1}\)\(y_j = y_{j - 1}\),那么对于任意 \(i\)\(j\)\(x_i \ne y_j\) 都有:

\[dp_{i, j, 0} = j - lst_{y, j} + 1 \quad dp_{i, j, 1} = i - lst{x, i} + 1 \]

对于转移,是好办的,显然:

\[dp_{i + 1, j, 0} \leftarrow dp_{i + 1, j, 0} + [x_{i + 1} \ne x_i] dp_{i, j, 0} + [x_{i + 1} \ne y_j] dp_{i, j, 1} \\ dp_{i, j + 1, 1} \leftarrow dp_{i, j + 1, 1} + [y_{j + 1} \ne x_i] dp_{i, j, 0} + [y_{j + 1} \ne y_j] dp_{i, j, 1} \]

做完了,答案即为 \(\sum_i \sum_j \sum_{k = 0} ^ 1 dp_{i, j, k}\)

code

2026.6.28

Cow and Treats

思考:33mins31s

AC:1h27mins16s

睡着了。

\(l_i\)\(r_i\) 表示第 \(i\) 头牛从左边或右边出发会在哪里入睡。对于每种方案,我们发现对于喜欢吃同一甜度的牛的集合,最多左右各放一个。我们考虑枚举 \(p\) 表示钦定左边出发的牛最远会睡在 \(p\) 的位置,枚举 \(i\) 表示牛喜欢的甜度,假设喜欢甜度 \(i\) 的牛中满足 \(l_j < p \land r_j > p\) 的个数为 \(cmid\),满足 \(l_j < p \land r_j \not> p\)\(cl\),满足 \(l_j \not< p \land r_j > p\)\(cr\) 个,那么 \(cmid\) 两边都可放,\(cl\) 只能左 \(ct\) 只能右,设 \(cnt_p\) 表示钦定了位置 \(p\) 后最多能有多少只牛睡下,\(dp_p\) 为其答案(后文省略下标 \(p\)),\(f_i\) 表示睡下 \(i\) 只牛的总答案,若 \(cl \ne 0 \land cr \ne 0\)\(cmid > 1\)\(cl \ne 0 \land cmid \ne 0\)\(cmid \ne 0 \land cr \ne 0\),那么其对 \(cnt_p\) 有二的贡献,有转移:

\[cnt \leftarrow cnt + 2 \quad dp \leftarrow dp \times (cmid (cmid - 1) + cl \times cmid + cl \times cr + cmid \times cr) \]

否则当三者其一不为 \(0\) 有转移 \(cnt \leftarrow cnt + 1\)\(dp \leftarrow dp + cl + cmid + cr\)。注意甜度为 \(s_p\) 要特殊处理。最后把 \(f_{cnt} \leftarrow f_{cnt} + dp\)。最后答案就是最大的 \(f_i \ne 0\)。做完了,具体细节看代码。

code

2026.6.29

Deterministic Heap (Easy Version)

思考:26mins11s

AC:1h9mins50s

简单 dp。

考虑 dp。我们注意到可以钦定每次递归到的点中左儿子大于右儿子,然后再将答案乘 \(2 ^ {n - 1}\) 即可。我们设 \(f_{i, j}\) 表示一个 \(i\) 层二叉树随便的加 \(j\) 次使得根为 \(j\),设 \(dp_{i, j}\) 表示第 \(i\) 层的两个点中左儿子大于右儿子且和为 \(i\) 的方案数,初始状态为 \(f_{0, 0, 0} = 0\)\(dp_{0, 0, 0} = 1\),那么显然有转移:

\[f_{i, j} = \sum_{s = 0} ^ j \sum_{x = 0} ^ s f_{i - 1, x} f_{i - 1, s - x} \\ dp_{i, j} = \sum_{s = 0} ^ j dp_{i - 1, j - s} \sum_{x = 0} ^ {\min(\lceil \frac j 2 \rceil - 1, s)} f_{i, x} \]

答案为 \(\sum_{i = 0} ^ k dp_{n - 1, i} \times 2 ^ {n - 1}\),做完了。前缀和优化可以做到 \(O(n k ^ 2)\)

code

Deterministic Heap (Hard Version)

AC:\(\infty\)

司马答辩题。感觉受到了强碱。

code

Find a car

思考:20mins

做不动了。已经在大战 2900 时红完了。

首先打表注意到 \(a_{i, j} = (i - 1) \oplus (j - 1) + 1\),并把原问题差分,我们现在要求的为 \(f(x, y) = \sum_i^{x - 1} \sum_j ^ {y - 1} [i \oplus j + 1 \le t] i \oplus j + 1\),我们发现对于一个 \((x - lowbit(x), x)\)\((y - lowbit(y), y)\) 的区域 \(y\) 坐标亦或上 \(x\) 坐标集合固定,类似 BIT 做即可。

code

2026.6.30

Region Separation

思考:41mins23s

被嘿题弄死了。

我们首先只考虑一次划分。我们注意到,对于划分成 \(k\) 份,要么划分不了要么只有一种方法。我们设 \(sum_x\) 表示子树和,整个树的和就应为 \(sum_1\)。我们设 \(f_k = \sum_{i = 1} ^ n [\frac{sum_1}{k} \mid s_x]\),那么对于 \(f_k = k\)\(k\) 是合法的。现在考虑怎么计算,枚举 \(i\),我们设 \(sum_i\) 能对划分成 \(x\) 的大小 \(k = \frac {sum_1} x\) 次的贡献,那么显然有 \(x \mid sum_1 \land x \mid sum_i\),即 \(x \mid \gcd(sum_1, sum_i)\),那么有 \(\frac {sum_1} {\gcd(sum_1, sum_i)} \mid k\)。我们考虑设 \(buc_x\) 表示满足 \(k = \frac {sum_1} {\gcd(sum_1, sum_i)}\)\(i\) 个数,那么有:

\[f_{x} = \sum_{k \mid x} buc_k \]

现在来算答案,设 \(dp_i\) 表示第一次划分为 \(i\) 份的答案,枚举下一次划分成多少份,有:

\[dp_i = [f_i = i] \times \sum_{i \mid k} dp_k \]

答案即为:

\[1 + \sum_i dp_i \]

\(1\) 为不分的方案数。做完了。

code

Attraction Theory

思考:55mins37s

呃呃呃不会。为什么天天都开到这些毒瘤题啊。。。/ll/ll

首先我们可以发现相邻两项的差只能为 \(0\)\(1\),并且注意到开头和结尾两端的相等的值个数可以为偶,其他的相等段都为奇数,那么我们就可以计数了。我们记 \(t_i\) 表示有多少个 \(k\) 使得 \(p_k = i\)\([L, R]\) 表示 \(t_i \ne 0\) 的区间,那么根据上面 \(t_L\)\(t_R\) 之外的 \(t_{\forall i \in (L, R)}\) 都应为偶数。为了方便,我们单独枚举 \(t_L\)\(t_R\) 的奇偶性。

先要注意,当 \(L = R\) 时显然可以单独算,后面枚举 \(len = R - L + 1\)\(len > 1\) 即可。

先假设两者全为奇数。我们枚举 \(len = R - L + 1\),插板法有方案数 \(\binom{\frac {n - len} 2 + len - 1}{len - 1}\),当 \(\frac {n - len} 2\) 不为整数无解,后面几种情况同理。为了计数,我们可以求出每个位置的 \(\sum t_i\),即每种情况下的个数总和,对于每个 \(i\) 贡献就应为 \(\sum t_i \times a_i\)。由于每个位置是等价的,那么对于 \(\sum t_i\) 在长度为 \(len\) 时都应相等,由于总个数为 \(n \times \binom{\frac {n - len} 2 + len - 1}{len - 1}\),那么每个 \(\sum t_i\) 就应为 \(\frac {n \binom{\frac {n - len} 2 + len - 1}{len - 1}} {len}\),那么答案就为:

\[\frac {n \binom{\frac {n - len} 2 + len - 1}{len - 1}} {len} \times \sum_{l = 1} ^ {n - len + 1} \sum_{i = l} ^ {r = l + len - 1} a_i \]

前缀和优化可以快速计算。

接下来计算右边和左边有一个为偶的。我们可以从左右刨去一个位置,钦定最左或最右要选,剩下的和全奇数就是一样的,单独算一下刨去的位置的贡献即可。剩下的 \(n - 1\) 个位置类比有贡献:

\[\frac {(n - 1) \binom{\frac {n - 1 - len} 2 + len - 1}{len - 1}} {len} \times \sum_{l = 1} ^ {n - len + 1} \sum_{i = l} ^ {r = l + len - 1} a_i \]

对于刨去的位置,如果是在左边,那么由于 \(L\) 可能的取值为 \([1, n - len + 1]\),那么贡献为 \(\sum_{i = 1} ^ {n - len + 1} \times \binom{\frac {n - 1 - len} 2 + len - 1}{len - 1}\);在右边的话,因为 \(R \in [len - 1, n]\),那么贡献有 \(\sum_{i = 1} ^ {n - len + 1} \times \binom{\frac {n - 1 - len} 2 + len - 1}{len - 1}\)。还是前缀和优化。

对于左右都为偶,同理,刨去两个位置,中间同全奇数,另外两个单独计算。

做完了,预处理逆元能做到 \(O(n)\)

code

Balanced Subsequences

思考:47mins15s

可不可以给我推道会做的题qwqwqwqwqwq

code

Tree Cutting (Hard Version)

AC:1.5h

终于是自己做的力。

首先对于原图,注意到有些点一定会赋成一个颜色,并一定形成一个子树,把所有一定要染成一个颜色的点缩成一个点。然后新图中会有 \(k\) 个点颜色固定,称为有色点,其他点怎么染都行。由于是分成 \(k\) 个连通分量,那么一定是一个有色点一个连通分量。我们考虑 dp,设 \(dp_{x, 0 / 1}\) 表示以 \(x\) 为根的子树中,\(x\) 所在的连通块不包含任何有色点或包含一个的方案数。对于有色点 \(x\),显然 \(dp_{x, 0} = 0\)。设儿子集合为 \(son(x)\),对于每个 \(to \in son(x)\) 若有颜色就断边没颜色直接连,那么 \(dp_{x, 1}\) 有转移:

\[dp_{x, 1} = \prod_{to \in son(x)} dp_{to, 0} + dp_{to, 1} \]

现在考虑无色点 \(x\)。对于 \(dp_{x, 0}\) 和儿子转移,因为 \(x\) 所在连通块子树内无有色点,那么对于儿子 \(to\) 依然有色断边无色直接连,有 \(dp_{x, 0} = \prod_{to \in son(x)} dp_{to, 0} + dp_{to, 1}\)。对于 \(dp_{x, 1}\),枚举其颜色和哪个儿子相同,有:

\[dp_{x, 1} = \sum_{to \in son(x)} dp_{to, 1} \times \prod_{v \in son(x) \land v \ne to} dp_{v, 0} + dp_{v, 1} \\ = \sum_{to \in son(x)} \frac {dp_{to, 1}} {dp_{to, 0} + dp_{to, 1}} \times dp_{x, 0} \]

做完了。

code

2026.7.1

Counting Cute Arrays

AC:2h

不行现在做题速度太慢了。

注意后文 \(a_i\) 等价于题面中 \(X_i\)

首先判无解是简单的不多说。考虑对于一个限制,假设为 \(a_i\),那么对于 \(\forall k \in (i, a_i)\),都应有 \(a_k \ge i\)。我们有了这条性质就可以计数了。设 \(dfs(l, r)\) 表示 \((l, r]\) 的答案,对于多元限制到 \(a_{a_{\cdots}} = -1\)\((i, a_i, a_{a_i}, \cdots)\),设其中不包含 \(l\) 的元素个数为 \(x\),方案数为 \(f = dfs(a_i, i - 1) \times dfs(a_{a_i}, a_i - 1) \cdots\),设 \(dp_{i, j}\) 表示前 \(i\) 个限制有 \(j\) 个可以作为 \(a_{k} = -1\)\(k\) 的前缀的方案数,那么有:

\[dp_{i, j} = f \times \sum_{k = j - x} ^ {r - l + 1} dp_{i - 1, k} \]

前缀和优化即可。

code

posted @ 2026-05-28 15:29  ACehomoxue  阅读(47)  评论(0)    收藏  举报