OI/ACM 做题记录
atcoder regular
- ARC166: C, D.\(\quad2024/8/5\)
- ARC167: D, E.\(\quad2024/8/9\)
- ARC168: C, D.\(\quad2024/8/14\)
atcoder grand
- AGC012: C,D,F.\(\quad2024/8/21\)
- AGC013: C(8/26).
XCPC
- HBCPC2024: F.\(\quad2024/8/14\)
DP
对 \(a\) 排序。观察到 \(b_i\in[a_i,a_{2n-i}]\),且 \(b_j\notin(b_{i},b_{i+1})\)。进一步,数列 \(b\) 只要满足这两个条件就是可被构造的。于是我们将问题转化为对满足以上二条件的数列 \(b\) 的计数。
观察到 \(b_n=a_n\)。不妨倒着计数,设 \(b_i=a_x\),若 \(b_{i-1}=a_y\),则接下来的 \(b_j\,(j<i)\) 不能再是下标 \(x,y\) 内(不包含)的 \(a\) 中元素。换言之,从后往前考虑到第 \(i\) 个数时,我们需要的状态实则是一个关于 \(i\) 两端都单调的区间 \([L_i,R_i]\),表示 \(b_{i-1}\) 在数列 \(a\) 的位置不能落在区间 \([L_i+1,R_i-1]\) 内部。
设 \(f_{i,x,y}\) 为倒着考虑至 \(b\) 的第 \(i\) 个元素,往前余下 \(x\) 个位置,往后余下 \(y\) 个位置的方案数,直接转移即可。注意处理两个数的值相同的情形。
图论
并查集
我们在任意两个可交换的球 \(x,y\) 之间连边,最终可得到一张具有若干连通块的图,其中同一连通块内的球都可互相交换。
对于同颜色交换的情形,若两个颜色均为 \(c\) 球 \(u,v\) 分别能与该颜色中重量最小的球 \(m_c\) 交换,则 \(u,v\) 就可通过 \(m_c\) 达到互换的效果;对于不同颜色交换的情形,若两个不同颜色的球 \(x,y\) 分别能与和它们颜色均不同的最小质量球交换,或与其中某球颜色相同的最小质量球交换,则他们之间也可交换。换言之,以同色或异色的最小质量球作为“中介”来实现与其他球的交换是最“节省”的方式。
综上,我们对每个球分别向同色和异色最小质量的球连边即可,实际实现可用并查集。一个连通块的方案数就是一个多重组合数。
DS
线段树
Luogu10863 [HBCPC2024] Enchanted
此题假强制在线(不知道有什么意义,无谓增加码量),实则可以离线。
这个合并的形式直接指向了二进制:为等级是 \(x\) 的书赋上权值 \(2^x\),则合并相当于加和并进位,操作 \(1\) 即是询问区间和的二进制最高位,操作 \(2\) 只需对比加上 \(2^k\) 前后二进制的变化。所有这些要求只需一棵线段树。
对于撤销操作,建出操作树:若该操作不撤销,则作为上一操作的子结点;若撤销至操作 \(p\),则成为 \(p\) 的子结点。最终 DFS 操作树,遍历时修改,回溯时还原即可。
Ad-hoc
[ARC168C] Swap Characters \(\quad\)| 枚举 & 组合数 \(\quad\|\texttt{2024/8/11}\)
设原串 \(s\) 有 \(x/y/z\) 个 \(A/B/C\)。对于一个新串 \(t\),设 \(f_{c_1,c_2}=\{(i,j):s_{i}=t_{j}=c_1,s_{j}=t_{i}=c_2\}\)。显然有 \(f_{c_1,c_2}=f_{c_2,c_1}\),且我们进行 \(f_{c_1,c_2}\) 次交换 \(c_1\) 与 \(c_2\) 后可将二者变为零,此时无法再仅通过此操作使 \(t\) 更接近 \(s\)。我们对 \(A/B,A/C,B/C\) 都进行如上的交换操作,不难发现最终余下的皆是 \(CAB\) 的轮换,或皆是 \(BCA\) 的轮换。
由此,枚举 \(f_{A,B},f_{A,C},f_{B,C}\) 以及轮换数量、轮换种类。我们以字符 \(A\) 为例,设轮换数为 \(p\),换成 \(B,C\) 的数量为 \(b,c\),则所有 \(A\) 中换掉 \(b+c+p\) 个。若轮换为 \(CAB\),则这 \(b+c+p\) 中应选出 \(c+p\) 个变为 \(C\),余下为 \(B\),如此则方案数为 \(\binom{x}{b+c+p}\binom{b+c+p}{b}\);轮换 \(BCA\) 同理为 \(\binom{x}{b+c+p}\binom{b+c+p}{c}\)。
[ARC167E] One Square in a Triangle \(\quad\|\texttt{2024/8/8}\)
没啥意义的奇怪题。
- 将蚂蚁看作直接穿过对方,得到所有蚂蚁的最终位置。
- 每只蚂蚁间的相对位置不变,故只需计算第一只蚂蚁到其起点之间还有多少蚂蚁。
- 模意义下,有蚂蚁经过第一只的起点,该值 \(+1\),反之 \(-1\),即使第一只蚂蚁本身经过它的起点也是如此。
贪心
[ARC166D] Interval Counts \(\quad\|\texttt{2024/8/5}\)
贪心。从左往右,若前一处须覆盖的小于等于该处,直接延长即可;否则,去掉尚未结束的最靠左起始的 \(y_i-y_{i-1}\) 条线段即可,可用队列实现。
[ARC167D] Good Permutation \(\quad\)| 并查集 & set \(\quad\|\texttt{2024/8/11}\)
显然应交换不在同一环中的数。贪心地,从前往后扫,往后找到最小的不在该环内的数交换。若当前元素已是环中最后元素,则无论如何必须交换。
那么是否会出现比 \(x\) 小且在另一环内的数在 \(x\) 之前的情形呢?注意到对于与 \(x\) 仍不同环的数,在 \(x\) 之前不可能具有比 \(x\) 更大的 \(y\),这是因为:若 \(y\) 是某环交换而来,则 \(y\) 不能大于 \(x\),否则换来的就是 \(x\);若 \(y\) 本身存在,则其必然与 \(x\) 或小于 \(x\) 的某数交换过。因此数 \(x\) 必须在位置 \(x\) 之前,否则不存在一个分布在 \(x\) 两侧的轮换满足所有在 \(x\) 前的都小于 \(x\)。如此一来,必有一个小于 \(x\) 且在位置 \(x\) 之前的 \(z\) 参与了 \(x\) 所在的轮换。如果我们要使 \(x\) 所在轮换并未被合并,就要求位置 \(z\) 之前的数皆小于 \(z\)(否则 \(z\) 将被交换,导致 \(x\) 被合并)。而这导致:第一。这些数只能在位置 \(z\) 之前的区域互相形成轮换,而不能有 \(z\) 之后的位置参与作用;第二,\(z\) 是第一个大于这些数的数。因此 \(z\) 必须被交换,从而 \(x\) 与这些轮换本身就已合并。因此,此算法保证了 \(x\) 不会主动与之前比他小的数交换。
实现时只需同时在并查集中维护集合最小元即可。
构造
首先有一些显然的构造方式,例如 \(1,1,\cdots,1,2,2,\cdots,2\),或者 \(1,2,3,\cdots,k,u,u+1,\cdots,u+m_1,\cdots,1,2,\cdots,n_s\) 等。对于前者,一个长度为 \(k\) 的块产生 \(2^{k-1}-1\) 的贡献;对于后者,一段长度为 \(m_r\) 的连续段产生 \(2^{mr}-1\) 的贡献。
然而这样的构造方式效率过低,无法在规定步数内达到要求。究其原因乃是一段产生的贡献并非 \(2^x\),而是 \(2^{x}-1\),需要用额外位置去弥补。故我们需要一种构造方式,使得产生的贡献是 \(2\) 的整次幂。
考虑如下方法:按照 \(N\) 的二进制位数,设 \(N\) 二进制下有 \(n\) 位,先放置 \(1,2,\cdots,n,1,2,\cdots,n\),如此已有 \(2^n-1\) 的贡献。观察到我们在后半段的第 \(i\) 个数(即以上序列的第 \(n+i\) 个位置)后插入一个大于前方所有数的 \(x\),就会额外产生 \(2^x\) 的贡献。故我们只需按 \(N-2^n+1\) 的二进制插入这样的 \(x\) 即可(大的数插入的位置应靠前)。
组合数学
计数数列与生成函数
斐波那契数列
[ARC166C] LU / RD Marking \(\quad\)| 多米诺骨牌 & 斐波那契组合意义 \(\quad\|\texttt{2024/8/5}\)
将网格线按斜对角“走楼梯”形划分,则每组间互不影响;单组内则转化为相邻格点不能同时选择的方案数问题,是经典的斐波那契数。则预处理斐波那契数列及其奇数前缀积即可。
斯特林数
Luogu4091 [HEOI2016/TJOI2016] 求和 \(\quad\)| 第二类斯特林数行和 \(\quad\|\texttt{2024/7/12}\)
代入斯特林数通项得
一遍 NTT 做完。
此外还有线性做法。

浙公网安备 33010602011771号