XCPC 训练题乱做

ECFinal2023 C. Equal Sums

Link

记值域为 \(w\) 并认为 \(n,m\) 同阶,直接背包的话和的值域能够达到 \(O(nw)\),统计每个答案的复杂度也是 \(O(nw)\),于是总复杂度是 \(O(n^3w)\)

注意到最后需要维护的信息仅仅是 \(\sum x_i = \sum y_j \Leftrightarrow \sum x_i - \sum y_j = 0\),记这个差为 \(d\),我们实际上能够通过调整两侧加入的顺序来将 \(d\) 控制在 \([-w,w]\)

具体而言,考虑若有 \(\sum_{i=1}^a x_i - \sum_{j=1}^b y_j = 0\),可以按如下算法构造一条从 \((0,0)\)\((a,b)\) 的路径:

  1. 设变量 \(i=0,j=0\) 表示当前位置,\(d=0\) 表示两侧和之差。

  2. \(d \leq 0\),令 \(d \leftarrow d+x_{i+1}, i \leftarrow i+1\).

  3. \(d > 0\),令 \(d \leftarrow d-y_{j+1}, j \leftarrow j+1\).

  4. \(i=a, j=b\) 时停止。可以发现 \(i=a\)\(i\) 不会再增加,\(j=b\)\(j\) 不会再增加,故一定能够停止。

  5. 由此构造出三元组序列 \(P=\{i_t,j_t,d_t\}\).

可以发现一个合法的 \(P\) 一定对应唯一的 \((\{x_i\},\{y_i\})\),故其构成双射。

整个过程中 \(d\) 都被控制在 \([-w,w]\) 内,于是设 \(dp_{i,j,d}\) 表示上述算法进行到状态 \((i,j,d)\) 的方案数,用一点前缀和优化转移。时间复杂度 \(O(nmw)\).

ECFinal2023 I. Balance

Link

考虑 \(x=\text{argmin}\{a_i\}, y=\text{argmax}\{a_i\}\),拉出 \(x \leadsto y\) 的任意一条路径 \((d_1=x,d_2,\cdots,d_k=y)\),然后:

\[\sum\limits_{(u,v) \in E} |a_u-a_v| \geq \sum\limits_{i=1}^{k-1} |a_i-a_{i+1}| \geq |a_x-a_y| = \max\{a_i\} - \min\{a_i\} \]

这跟题目给出的不等号方向相反,所以所有不等号都必须取等,也就是说:

  • 路径上点权递增,即 \(\forall t \in [1,k), a_{d_i} < a_{d_{t+1}}\).

  • 除了路径的其他边的两个端点权值必须相等,即 \(\forall (u,v) \notin E(\text{path}), a_u=a_v\).

  • 推论:任意一个点的点权必须在路径上出现过,即 \(\forall u \in V, \exist x \in V(\text{path}), a_u=a_x\).

于是将所有出现的点权排序并记 \(c_i\) 表示第 \(t\) 大点权有多少个点。枚举 \(x \leadsto y\) 的路径的 LCA,分别考虑 LCA 的前后路径。以前面的路径为例,记第 \(t\) 大点权深度最浅的点是 \(b_i\),那么必须有 \(siz_{b_i} = \sum_{j=1}^t c_j\)\(b_i \in subtree_{b_{t+1}}\).

注意到对于一个点 \(u\),满足 \(siz_u = \sum_{j=1}^t c_j\)\(t\) 至多只有一个,记为 \(f_u\)(若不存在则为 \(0\))。直接转移即:

\[f_u = [siz_u = \sum_{j=1}^t c_j] \cdot [\max\limits_{v \in subtree_u}\{f_v\} = t-1] \]

DP 完枚举 LCA 统计即可,一车细节。时间复杂度 \(O(n)\).

ECFinal 2022 A. Coloring

Link

称颜色为 \(1\) 的点为黑点,为 \(0\) 的点为白点。

首先连边 \((a_i,i)\),由于每个点入度均为 \(1\),图一定是外向基环树(只关心 \(s\) 所在的连通块,可能有自环)。

先只考虑环上,容易发现任意时刻环上黑点一定形成一个区间 \([l,r]\),并且它们可以不断向右移动。枚举最后 \(l,r\) 的值以及转了几圈,就可以确定每个点变化了多少次(以及最后的颜色)。

再考虑每棵子树,环上点颜色变化的次数决定了一条链上黑白交替的最大次数。设 \(f_{u,t},g_{u,t}\) 表示黑白交替了变化 \(t\) 轮且最后是黑点/白点的最大贡献,树上 DP 即可。

枚举 \(l,r\) 可以用前缀和优化,一百车细节。时间复杂度 \(O(n^2)\).

ECFinal 2022 B. Binary String

Link

这不是我出的题吗

alt text

不过其实环上的问题不需要转换成序列做。找到上面提到的循环移位,然后按转化后的操作容易维护某时刻所有 \(R\) 的位置(虽然这题并不需要)。

这题里扫一遍求出 \(R\) 什么时候停止移动,然后跑 KMP 算出最小周期即可。复杂度 \(O(n)\).

ECFinal 2021 C. String-dle Count

Link

所有信息可以转化为四种限制:

  1. 位置 \(p\) 上必须填字母 \(c\)

  2. 位置 \(p\) 上不能填字母 \(c\)

  3. 字母 \(c\) 出现了恰好 \(t\) 次。

  4. 字母 \(c\) 出现了至少 \(t\) 次。

直接子集卷积是 \(O(|\Sigma| k^2 2^k)\),无法通过。

利用一些性质,记字母 \(c\) 出现次数的下限为 \(f_c\),那么必须有 \(\sum_c f_c \leq k\),否则必然无解。

一个神奇的 trick:记 \(dp_{i,state}\) 表示填前 \(i\) 个位置,状态为 \(state\) 的方案数。\(state\) 记录每种字符 \(c\) 填了超过 \(f_c\) 个 / 未超过 \(f_c\) 个且具体填了几个。

实现时可以新建一个序列,填入 \(f_c\) 个字符 \(c\),然后直接用二进制数状压 \(state\)。总时间复杂度 \(O(|\Sigma| k 2^k)\).

Ptz2024 Day3 C. Yet Another Shortest Path Query

Link

平面图 Trick 题。

平面图满足性质 \(m \leq 3n-6\),由抽屉原理可得至少有一个点度数不超过 \(5\)。于是不停地删去度数 \(\leq 5\) 的点,得到每个点被删去的时间戳 \(p_u\)

考虑将每条边 \((u,v)\) 看作两条有向边 \(u \to v\), \(v \to u\)

  • \(p_u > p_v\),记该边为 R 型边。每个 \(u\) 至多只有 \(5\) 条 R 型出边。

  • \(p_v < p_u\),记该边为 L 型边。每个 \(v\) 至多只有 \(5\) 条 L 型入边。

接下来考虑可能的路径类型,先考虑 \(len=3\),记 X 表示 L 或 R:

  • RXX:枚举 \(s\) 的 R 型出边,转化为 \(5\)\(len=2\) 的子问题。

  • XXL:枚举 \(t\) 的 L 型入边,转化为 \(5\)\(len=2\) 的子问题。

  • LRR:按 \(s\) 离线,枚举 \(s\) 的所有 L 型出边再枚举两层 R 型出边,\(25\) 次枚举.

  • LLR:按 \(t\) 离线,枚举 \(t\) 的所有 R 型入边再枚举两层 L 型入边,\(25\) 次枚举.

LRRLLR 的复杂度大约为 \(O(50m)\),同时产生了至多 \(10q\)\(len=2\) 子问题。

对于 \(len=2\),同样:

  • RX:枚举 \(s\) 的 R 型出边,转化为 \(5\)\(len=1\) 的子问题。

  • XL:枚举 \(t\) 的 L 型入边,转化为 \(5\)\(len=1\) 的子问题。

  • LR:按 \(s\) 离线,枚举 \(s\) 的所有 L 型出边再枚举一层 R 型出边,\(5\) 次枚举.

LR 的复杂度大约为 \(O(10q+m) \cdot 5 = O(50q+5m)\),同时产生了至多 \(100q\)\(len=1\) 子问题。

对于 \(len=1\),直接枚举 \(s\) 的 R 型出边和 \(t\) 的 L 型入边。这里的复杂度大约为 \(O(1000q)\).

于是总复杂度上界大概是 \(O(1000q+50m)\)。注意实现时 \(len=1\) 的子问题可以直接计算,不需要存下来。

Ptz2024 Day3 I. Dreamy Putata

Link

列出方程,发现每一层可以由上面两层递推而来。假设不考虑 \((tx,ty)\) 处方程的特殊性,直接以前两层 \(2m\) 个点为主元,用线段树维护矩阵乘法计算转移矩阵,最后再以第一行和最后一行导出的方程组高斯消元即可。

但是 \((tx,ty)\) 处方程不一样,为 \(f_{tx,ty}=0\),所以 \(f_{tx+1,ty}\) 实际上是没有办法用前两层的主元推出的。所以设 \(f_{tx+1,ty}\) 为一个新的主元,同时由于 \(f_{tx+1,ty}\) 可以用前两层主元表示,新增了一个方程组,故最后得到的方程组数量和主元数量还是一致的。

注意上述做法有一车特殊情况,比如 \(tx=0\)(新主元和原主元会重复),\(tx=n-1\)(没有新主元,第一行少导出一个方程组)。以及由于 \(tx\) 前后转移不一样,需要分段算;以及方程里的常数项导致需要新开一个矩阵乘法线段树。

总时间复杂度 \(O(q (2m)^3 \log n)\).

CCPC Final 2023 B. Periodic Sequence

Link

首先找上界。有一个显然的结论:对于任意一个可能出现的字符串 \(S_i\),一定存在 \(k \leq |S_1|\) 使得 \(S_i = S_1[1:k] + S_1[1:i_1] + \cdots + S_1[1:i_t]\),其中 \(1 \leq i_1, i_2, \cdots, i_t \leq k\)。容易归纳证明。

所以上界显然就是令 \(S_1 = \text{'a'}+\text{'b'} \times (n-1)\) 时,所有这样的序列的个数,下面证明存在一个字符串序列能将它们全部串起来。

\(n\)\(1\) 枚举 \(k\)。对于某个 \(k\),把所有字符串连成一棵树,\(S_i = S_1[1:k] + S_1[1:i_1] + \cdots + S_1[1:i_t]\) 即看作依次走边 \(i_1,i_2,\cdots,i_t\) 到达的点。显然所有深度不超过 \(l-k\) 的点与所有可能的字符串一一对应。

那么假设现在字符串序列的末尾对应的节点是 \(u\),添加一个新的串在树上对应:

  1. 对于所有 \(u\) 的儿子 \(v\),可以走到 \(v\)(对应新增一个前缀)。

  2. 对于所有 \(u\) 的祖先 \(x\),若 \(y\)\(x\) 的某个更小的兄弟,则可以走到 \(x\)\(y\)(对应删去一个后缀)。

  3. 可能可以走到比儿子更深的节点,但此证明中不考虑。

按深度归纳证明如果初始时在根节点,那么可以遍历树上所有节点(并在某个节点停止)。假设根节点的儿子(按边权从小到大)依次为 \(s_1,s_2,\cdots,s_k\),且 \(s_i\) 子树下按归纳假设构造的路径停止在 \(t_i\) 节点,那么直接按照以下方式构造:

\[\text{root} \to s_k \leadsto t_k \to s_{l-1} \leadsto t_{l-1} \to \cdots \to s_1 \leadsto t_1 \]

最后,对于不同的 \(k\),也可以类似上面的路径从大到小把根串起来。于是证明了存在一个字符串序列能将它们全部串起来,即上限能达到。


接下来考虑计数,枚举 \(k\),则有:

\[\begin{aligned} f(l) &= \sum\limits_{k=1}^l [x^l] \dfrac{1}{1-x} \cdot x^k \cdot \text{SEQ}[x+x^2+\cdots+x^k] \\ & = [x^l] \sum\limits_{k=1}^l \dfrac{x^k}{1-2x+x^{k+1}} \\ \end{aligned} \]

一种暴力做法是对于某个 \(k\),转成线性递推,可以 \(O(n)\) 算出所有系数。

另一种做法是暴力拆开:

\[\begin{aligned} [x^l] \dfrac{x^k}{1-2x+x^{k+1}} &= [x^{l-k}] \sum\limits_{t \geq 0} x^t (2-x^k)^t \\ &= \sum\limits_{t \geq 0} [x^{l-k-t}] (2-x^k)^t \\ (\text{let } t = l-kr,) &= \sum\limits_{r \geq 0} [x^{kr-k}] (2-x^k)^{l-kr} \\ &= \sum\limits_{r \geq 0} \dbinom{l-kr}{r-1} (-1)^{r-1} 2^{l-(k+1)r+1} \\ \end{aligned} \]

注意这里出现了 \(kr\),于是考虑根号分治。对于 \(k < B\),用前面提到的暴力做法;对于 \(k \geq B\),一定有 \(r \leq \lfloor n/B \rfloor \triangleq B_0\),然后枚举 \(r\)

\[\begin{aligned} f_0(l) &= \sum\limits_{k=B}^l \sum\limits_{r \geq 0} \dbinom{l-kr}{r-1} (-1)^{r-1} 2^{l-(k+1)r+1} \\ &= \sum\limits_{r=0}^{B_0} (-1)^{r-1} 2^{l-r+1} \sum\limits_{k=B}^l \dbinom{l-kr}{r-1} 2^{-kr} \\ \end{aligned} \]

\[g_{r,l} \triangleq \sum\limits_{k \geq B} \dbinom{l-kr}{r-1} 2^{-kr} \\ \begin{aligned} g_{r,l+r} &= \sum\limits_{k \geq B} \dbinom{l+r-kr}{r-1} 2^{-kr} \\ &= \sum\limits_{k \geq B-1} \dbinom{l-kr}{r-1} 2^{-(k+1)r} \\ &= 2^{-r} \Big[ g_{r,l} + 2^{-r(B-1)} \dbinom{l-r(B-1)}{r-1} \Big] \\ \end{aligned} \]

\(B = O(\sqrt n)\),时间复杂度 \(O(n \sqrt n)\)

CCPC Final 2023 K. Sticks

Link

场上推出来结论,调了半天发现好像假了,换了个容斥做法赛后又调了一晚上。结果在写这篇题解的时候突然发现场上做法没假,改了三行过了...

设左侧第 \(i\) 行的棍子长度为 \(x_i\),上方第 \(j\) 列的棍子长度为 \(y_j\)

定义:对于一种摆放方式,若 \(\forall i \in [1,n], y_{x_i+1} \neq i\),称其该摆放方式合法,即不存在以下形状:

...|
...|
-->∨

Lemma 1. 任意一个可能达到的矩阵 \(A\) 都存在至少一种合法摆放方式。

Proof 1. 对于 \(A\) 的任意一种摆放方式,找到最小的 \(x_i\) 使得 \(y_{x_i+1} = i\) 并令 \(y_{x_i+1} \leftarrow y_{x_i+1}-1, x_i \leftarrow x_i+1\)。调整后冲突的最小 \(x_i\) 至少增加 \(1\),故有限次调整后能找到一种合法摆放方式。

Lemma 2. 任意零一矩阵 \(A\) 至多只有一种合法摆放方式。

Proof 2. 枚举 \(k=n,n-1,\cdots,1\),不断执行以下流程:

  • 求出 \(t \in [0,k]\) 满足 \(A_{k,1}=A_{k,2}=\cdots=A_{k,t}=1, A_{k,t+1}=0\). 那么必然有 \(y_k=t\),且若 \(s>t, A_{k,s}=1\) 则有 \(x_s = k\) 并删去第 \(s\) 行(若不全为 \(1\) 则终止)。

该流程要么提前终止,要么给出唯一的合法摆放方式并且没有其他可能。

Collary. 所有可能达到的矩阵 \(A\) 与合法摆放方式构成双射。


于是现在问题变为了计数满足 \(\forall i \in [1,n], y_{x_i+1} \neq i\)\((\{x_i\},\{y_i\})\) 序列数量。

\(dp_{i,j}\) 表示考虑前 \(i\) 列且 \(\max_{t=1}^i \{y_t\}=j\)。转移考虑分成

  1. \(y_{i+1} \leq j\),则转移为 \(dp_{i,j} \to dp_{i+1,j}\),系数直接乘上方案数即可。

  2. \(y_{i+1} > j\),则转移为 \(dp_{i,j} \to dp_{i+1,k} (k>j)\),相当于要求 \(x_{j+1}, x_{j+2}, \cdots, x_{k-1} \leq i\)\(x_k < i\),分步转移即可。

总时间复杂度 \(O(n^2)\)

CCPC Final 2023 M. Bot Friends

Link

[注:暂时无法确认本篇题解完全正确]

首先注意到没有 bot 能到达 \(0\)\(n+2\) 位置(容易反证),也就是说 bot 只能到达 \(n+1\) 个坑,那么必然恰有一个坑最后是空的。

同理,只考虑区间 \([l,r]\) 内的 bot,如果最后空出来的坑在最左边,称这个区间为 R 型块;如果最后空出来的坑在最右边,称这个区间为 L 型块。那么考虑整个过程,依次考虑每一步:

  1. 每一步中,如果移动的机器人向右并且它右边紧挨着一个 L 型块,那么它与 L 型块合并成一个新的 R 型块并重复这个过程;否则它自己成为一个新的 R 型块。

  2. 如果移动的机器人向左并且它左边紧挨着一个 R 型块,那么它与 R 型块合并成一个新的 L 型块并重复这个过程;否则它自己成为一个新的 L 型块。

所以整个过程始终只有未操作的 bot,L 型块与 R 型块。那么最后的局面一定是左边若干 L 型块 + 右边若干 R 型块。问题就是最小化未能合并(自己成为一个新块)的 bot 数量。

同时注意到如果在合并过程中建边,会形成一棵类似表达式树的结构,如:

  • R 型块 = '>' + (L型块)*;或者 R 型块 = '>'(花费 \(1\) 代价)

  • L 型块 = (R型块)* + '<';或者 L 型块 = '<'(花费 \(1\) 代价)

分析到这里已经可以区间 DP,记 \(f_{l,r},g_{l,r}\) 分别表示 \([l,r]\) 为 L 型块与 R 型块时的最小代价。时间复杂度 \(O(n^3)\)

既然是表达式树,就可能可以通过从左到右扫描并维护栈来描述它。先只考虑最后全为 L 型块的情况(即最后状态的一个前缀),可以将 > 类似看作左括号并将 < 类似看作右括号,有如下规则:

  • 遇到 >:在栈上插入一个 >;如果下一个 bot 立刻将它删去,则会产生 \(1\) 的代价(对应 R 型块 = '>')。

  • 遇到 <:弹栈一次;或者花费 \(1\) 代价不删除(对应 L 型块 = '<')。

于是直接记 \(dp_{i,j,0/1}\) 表示处理到第 \(i\) 个 bot,栈内有 \(j\)>,第 \(i\) 个 bot 是否是 > 的最小代价,容易转移。

最后对左右各做一次,枚举最后状态的坑位置合并即可。时间复杂度 \(O(n^2)\)

ECFinal 2019 B. Black and White

Link

经过多番尝试之后,一步一步考虑基本上不可能很好地挖掘性质。一个好的想法是两步两步考虑。

首先对于考虑 \(2 \nmid n+m\) 的情况,可以枚举第一步来转化为 \(2 \mid n+m\)

那么现在 \(n+m\) 步被划分为了 \((n+m)/2\) 组。记向上走为 A,向右走为 B,考虑两种贡献计算方式:

  1. 向右走时不计算贡献,向上走时计算左侧的贡献。容易发现 AA 和 BB 始终不产生贡献,而剩下两种:
(x mod 2, y mod 2) BA AB
\((0,0)\) \(1\) \(0\)
\((1,1)\) \(0\) \(-1\)
  1. 向上走时不计算贡献,向右走时计算上方的贡献。这时贡献的计算与 \(n\) 奇偶性有关:
(x mod 2, y mod 2) BA(2 | n) AB (2 | n) BA (2 ∤ n) AB (2 ∤ n)
\((0,0)\) \(0\) \(-1\) \(1\) \(0\)
\((1,1)\) \(1\) \(0\) \(0\) \(-1\)

看起来没有规律很难处理,但是如果我们把两种计算方式加起来(算两次),就会发生神奇的事情:

(x mod 2, y mod 2) BA(2 | n) AB (2 | n) BA (2 ∤ n) AB (2 ∤ n)
\((0,0)\) \(1\) \(-1\) \(2\) \(0\)
\((1,1)\) \(1\) \(-1\) \(0\) \(-2\)
  • 先考虑 \(2 \mid n,m\),此时贡献已经跟位置没有关系了,直接枚举 BA 填了 \(t\) 个,AB 填了 \(t-k\) 个,可以算出 AA 和 BB 的数量,然后直接可重排:

\[Ans = \sum\limits_{t=\max\{0,2k\}}^{\min\{n,m\}/2+k} \dbinom{(n+m)/2}{t,t-2k,n/2-t+k,m/2-t+k} \]

  • 对于 \(2 \nmid n,m\),注意到如果给每个 \((0,0)\) 减一,给每个 \((1,1)\) 加一,就可以归到前一种情况。而 \((0,0)\) 一定比 \((1,1)\) 多一,因此先把 \(k\) 减一再照前一种情况做即可。

时间复杂度 \(O(T\min\{n,m\})\).

CCPC2024 Harbin H. Subsequence Counting

Link

首先把逆变换变成正的。求出 \(k\) 在模 \(L\) 意义下的逆元 \(d\),则 \(s'_i = s_{id \bmod k}\).

注意到 \(m\) 很小,这启发我们可以把 DP 写成矩阵形式,每个矩阵大小是 \(m+1\). 那么问题变成:现有 \(n\)\(L\) 个矩阵,求它们在经过变换重排后的乘积。如果记原本的矩阵序列为 \(s_0,s_1,\cdots,s_{L-1}\),那么就是要求(以下均省略下标的模 \(L\)):

\[s_0 s_d s_{2d} s_{3d} \cdots s_{(L-1)d} \]

记这个问题为 \(f(L,d,n)\),神奇的是,这竟然可以用类似欧几里德的方法进行递归。

考虑将原本序列每隔 \(d\) 个就换一次行,类似:

\[\begin{matrix} s_0 & s_1 & s_2 & \cdots & s_{(L-1) \bmod d} & \cdots & s_{d-1} \\ s_d & s_{d+1} & s_{d+2} & \cdots & s_{(L-1) \bmod d + d} & \cdots & s_{2d-1} \\ \vdots & \vdots & \vdots & \ddots & \vdots & \ddots & \vdots \\ s_{kd} & s_{kd+1} & s_{kd+2} & \cdots & s_{L-1} \\ \end{matrix} \]

那么,要求的矩阵乘积就变成了:从左到右对每一列求乘积,再按照跳跃顺序将这些列的乘积相乘。跳跃的顺序为:\(0, d-(L \bmod d), 2[d-(L \bmod d)], \cdots\).

而由于原本只有 \(n\) 段矩阵,所以乘积不一样的列只有至多 \(n+1\) 个,并且可以在找出所有断点后用线段树维护。于是可以获得每一列的乘积。

这样就变成了一个子问题 \(f(d, d-(L \bmod d), n+1)\),可以递归下去。

这里有一个小问题:如果 \(d\) 很接近 \(L\),那么递归的子问题规模并没有减少太多。不过注意到此时我们可以令 \(d\) 变成 \(L-d\),即:

\[s_0 s_{-d} s_{-2d} s_{-3d} \cdots s_{-(L-1)d} = s_0 s_{(L-1)d} s_{(L-2)d} s_{(L-3)d} \cdots s_{d} \]

也即把 \(s_0\) 后面的矩阵顺序翻转。这很容易实现,并且至多只会让段数增加 \(1\).

于是这样,每两次递归后 \(d\) 至少会减半,递归深度至多 \(O(\log L)\),并且矩阵增加的端数也是至多 \(O(\log L)\)。每次递归时需要用线段树维护区间乘矩阵,总复杂度是 \(O(m^3 n \log n \log L)\).

CCPC2023 Shenzhen B. Excuse

Link

每个 \(a_i\) 都服从几何分布,并且 \(P[a_i=k] = 2^{-k-1}\).

首先拆期望 \(E[X]=\sum_{k \geq 1} P[X \geq k]\),而 \(\text{mex} \geq k\) 就是 \(0,1,\cdots,k-1\) 都出现过。记 \(X \geq k\) 的概率为 \(s_k\).

“都出现过”的限制很容易让人想到容斥,但是尝试之后根本没法做。我们尝试用更根本和暴力的办法:直接写成指数型生成函数。

\[\hat F_t(x) = \sum\limits_{i \geq 1} \dfrac{1}{i!} (x/2^{t+1})^i = e^{x/2^{t+1}} - 1, \text{ for } x = 0,1,\cdots,k-1 \]

\[\hat F_k(x) = \sum\limits_{i \geq 0} \dfrac{1}{i!} (x/2^{k+1})^i = e^{x/2^{k+1}} \]

\[s_k = n! [x^n] \prod_{t=0}^{k-1} \hat F_t(x) \cdot \hat F_k(x) = n! [x^n] \prod_{t=0}^{k-1} (e^{x/2^{t+1}} - 1) \cdot e^{x/2^{k+1}} \]

注意到连乘号里面对于不同的 \(k\) 相当于求前缀积,这引发一个大胆的想法:尝试直接求出这个无限乘积,尽管现在我们无法确信它一定收敛。

但是注意到里面每一项都没有常数项,所以至少先对每一项提出 \(x\),得到:

\[s_k = n! [x^n] \dfrac{x^k}{2^{k(k+1)/2}} e^{x/2^{k+1}} \prod_{t=0}^{k-1} (e^{x/2^{t+1}} - 1) = n! [x^n] \dfrac{x^k}{2^{k(k+1)/2}} e^{x/2^{k+1}} \dfrac{G(x)}{G(x/2^k)} \]

\[G(x) = \prod_{t=0}^{+\infty} (e^{x/2^{t+1}} - 1) \]

直接取对数。先求出 \(H(x) = \ln \frac{e^x-1}{x}\) 的泰勒展开。展开形式和伯努利数有些联系,不过这里可以直接求多项式的 \(\ln\)。 接下来:

\[\ln G(x) = \sum_{t=0}^{+\infty} \sum\limits_{t \geq 1} H \Big(\dfrac{x}{2^t}\Big ) = \sum\limits_{i \geq 1} h_i \sum\limits_{t \geq 1} \Big( \dfrac{x}{2^t} \Big)^i = \sum\limits_{i \geq 1} \dfrac{2^{-i}}{1-2^{-i}} h_i x^i \]

所以 \(G(x)\) 确实是收敛的,直接对上式求多项式 \(\exp\) 即可得到 \(G(x)\) 的多项式展开。

最后,计算答案:

\[Ans_n = \sum\limits_{k \geq 1} s_k = n! [x^n] G(x) \sum\limits_{k \geq 1} \dfrac{x^k}{2^{k(k+1)/2}} \dfrac{e^{x/2^{k+1}}}{G(x/2^k)} \]

\(P(x) = e^x / G(x)\)\(Q(x) = \sum\limits_{k \geq 1} \dfrac{x^k}{2^{k(k+1)/2}} P(x/2^k)\),则:

\[P(x/2^k) = \sum\limits_{i \geq 0} p_i 2^{-ki} x^i \]

\[q_t = \sum\limits_{k=1}^t 2^{-k(k+1)/2} p_{t-k} 2^{-k(t-k)} \]

\(d=t-k\),用 Bluestein Method:

\[2^{-k(k+1)/2} p_d 2^{-kd} = (2^{-1})^{\binom{k+d}{2}} \Big[ \dfrac{1}{2^{k(k+1)/2}} 2^{\binom{k}{2}} \Big] \Big[p_d 2^{\binom{d}{2}} \Big] \]

于是直接一次卷积即可获得所有 \(Ans_n\) 的值。时间复杂度 \(O(n \log n)\).

Jilin 2023 H. Games on the Ads 2: Painting

Link

显然每个格子都会恰好被行染一次,被列染一次。讨论一下情况:

  • 如果 \(c_{i,j} \neq p_i, c_{i,j} \neq q_j\),那么整个无解。
  • 如果 \(p_i = q_j\),那么无论怎么染这个格子都合法。
  • 否则如果 \(c_{i,j} = p_i\),那么必须先染列再染行;反之亦然。

于是问题转化为给定一个 \(n + n\) 的二分图,且每个点度数均为 \(n-1\),求拓扑排序数量。

少了 \(n\) 条边让人很苦恼,直接大力枚举 \(2^n\) 种给边定向,这样就变成了完全二分图。

这意味着如果确定了列的染色顺序,每个行插入的位置是固定的。

\(S_i\) 表示行 \(i\) 被连向的点的集合(即必须在它之前染的列号)。将所有 \(S_i\) 按照集合大小排序,设为 \(S_{i_1}, S_{i_2}, \cdots, S_{i_n}\)

  • 如果存在 \(S_{i_t} \not\subseteq S_{i_{t+1}}\),那么无解。
  • 否则,设大小为 \(k\) 的集合有 \(c_k\) 个,那么方案数为 \(\prod_{k=1}^n c_k!\)

时间复杂度 \(O(n 2^n)\).

Zhejiang 2024 K. Sugar Sweet 3

Link

首先,这就是摩尔投票法,因此最后的局面只由 \(A,B,C\) 决定。最后牌堆里没有牌当且仅当 \(2 \mid A+B+C\)\(2 \max\{A,B,C\} \leq A+B+C\)

考虑按每次牌堆清空的节点将整个过程分成若干段。称每一段内第一次操作的颜色为该段的主色,那么该段内主色和非主色构成了一个括号序列。这就是整个问题的结构。

对于三种牌数量的限制 \(A,B,C\),可以枚举每种颜色作为主色的数量 \(a,b,c\),然后设每种主色对应的段中,非主色数量的分配具体为:

\[\begin{matrix} \text{Color 1} & a & i_{(b)} & a-i_{(c)} \\ \text{Color 2} & b & j_{(c)} & b-j_{(a)} \\ \text{Color 3} & c & k_{(a)} & c-k_{(b)} \\ \end{matrix} \]

\[\begin{cases} i-k = B-b-c \\ j-i = C-c-a \\ k-j = A-a-b \\ \end{cases} \]

注意到由于 \(a+b+c=A+B+C\),故只需要枚举 \(a,b\);但是方程组不满秩,故还需要再枚举 \(i\)。枚举 \((a,b,i)\) 后剩下的 \((j,k)\) 可以直接求出。


接下来,枚举三种主色对应段的数量 \(p,q,r\)。那么以主色 \(1\) 为例,将非主色看成一种颜色,只需要求出将 \(2a\) 个括号分为 \(p\) 段括号序列的方案数 \(f(a,p)\),再乘上 \(\binom{a}{i}\) 即可。最后再乘上 \(\binom{p+q+r}{p,q,r}\) 后求和即得到答案。

先考虑求出 \(f(n,k)\) 的值,就是

\[f(n,k) = [x^n] (\sum\limits_{i \geq 1} Cat_i x^i)^k \]

可以直接 DP 求出;也可以在每个括号序列后加一个右括号,映射为 \((0,0)\) 走到 \((2n+k,-k)\) 的路径数:

\[f(n,k) = \dbinom{2n+k-1}{n} - \dbinom{2n+k-1}{n-1} \]

接下来,恰有 \(s\) 段的方案数为:

\[\begin{aligned} c_s &= \dbinom{a}{i} \dbinom{b}{j} \dbinom{c}{k} \sum\limits_{p+q+r=s} \dbinom{s}{p,q,r} f(a,p) f(b,q) f(c,r) \\ &= \dbinom{a}{i} \dbinom{b}{j} \dbinom{c}{k} s! \sum\limits_{p+q+r=s} \dfrac{f(a,p)}{p!} \dfrac{f(b,q)}{q!} \dfrac{f(c,r)}{r!} \\ &= \dbinom{a}{i} \dbinom{b}{j} \dbinom{c}{k} s! [x^s] \Big( F_a(x) F_b(x) F_c(x) \Big) \\ \end{aligned} \]

\[\text{where } F_a(x) = \sum\limits_{p=0}^a f(a,p) \dfrac{x^p}{p!} \]

暴力多项式乘法十分爆炸,不过注意到我们实际上要求的是很多个这样的多项式乘积之和,故可以直接插值,这样就变成了点值乘法。

预先将所有 \(F_a(x)\) 和点值处理出来,然后枚举 \(a,b,i\) 的值并累加点值,最后还原即可。总时间复杂度为 \(O(n^3)\),常数小。

3rdUCup Stage40 D. Fern Market

Link

首先如果不考虑计数,这就是那个广为人知的经典反悔贪心题
CF865D Buy Low Sell High
。做法是:

  • 维护一个小根堆。从前往后考虑每一天,设价格为 \(p_i\)
    • 如果堆内没有比 \(p_i\) 小的元素,则将 \(p_i\) 入堆。
    • 否则将堆顶元素 \(x\) 出堆,答案加上 \(p_i - x\),然后将 \(p_i\) 入堆两次。

考虑枚举 \(t\),然后统计 \([t,t+1)\) 被算进的贡献。将 \(\leq t\) 的元素标为 \(0\),将 \(>t\) 的元素标为 \(1\),则共有 \(t\)\(0\)\(n-t\)\(1\)。会发现按照上述策略等价于对这个新的序列进行反悔贪心:

  • 如果 \(p_i = 0\),那么无论什么情况最后都会往堆里放入一个 \(0\)
  • 如果 \(p_i = 1\),且栈内有 \(0\),则出栈一个 \(0\) 并入栈两个 \(1\)
  • 如果 \(p_i = 1\),且栈内没有 \(0\),则无论什么情况最后都会往堆里放入一个 \(1\)

也就是说,一定能够取到最大值。考虑贪心:

\(0\) 看为向右上走一步,将 \(1\) 看为向右下走一步,但已经在 \(0\) 时遇到 \(1\) 只能水平向右走一步,并将这种情况记作“损失”。那么对于一个序列,其最后的贡献就是 \(1\) 的数量减去“损失”发生的次数。

所有 \(1\) 的数量很好算,就是 \((n-t) \binom{n}{t}\)

对于“损失”,有结论:如果不管在 \(0\) 时遇到 \(1\) 只能水平向右走一步的限制,直接按照普通 Dyck Path 的规则,则“损失”数量等于最低点高度的相反数。

于是枚举 \(r \leq -1\),统计最低点至少低于 \(r\) 的 Dyck Path 数量,最后求和即可。

最后推出来的答案是一个上指标为 \(n\) 的组合数前缀和。故枚举 \(n\),先预处理组合数前缀和,然后再 \(t\) 统计答案即可。时间复杂度 \(O(k^2)\).

posted @ 2024-12-21 19:28  苹果蓝17  阅读(155)  评论(1)    收藏  举报