IOI2025集训队互测 W3
Day7(20241029)
卡了一场 T2,结果还是 MLE 了,我不懂得欣赏。
T1 Cyberangel
我们考虑按照值域从小到大依次加入每一个数,发现需要处理的就是当前所有的区间的最大值之和为多少。
由于所有的区间这个信息不太好处理,所以我们考虑分治处理,对于所有 \([l,r]\subseteq [L,R]\) 的区间,记 \(mid=\dfrac{L+R}{2}\),我们先处理所有 \(l\le mid< r\) 的区间。
我们还是从小到大依次加入每一个数,或者说其余的所有数认为是 \(0\),那么我们可以对每一个位置 \(i\) 统计为最大值为 \(a_i\) 的区间数量。
如果 \(i\in [L,mid]\),则要求 \(i\) 是 \([L,mid]\) 这一段的后缀最大值,它的贡献为 \(a_i\times (i-pre_i)\times (y_i-mid-1)\),其中 \(pre_i\) 是比 \(i\) 小的下一个后缀最大值的下标,\(y_i\) 为最小的 \(j\in[mid+1,r]\) 使得 \(a_j>a_i\),若不存在则令 \(j=r+1\)。
如果 \(i\in [mid,R]\),则要求 \(i\) 是 \([mid,R]\) 这一段的前缀最大值,它的贡献为 \(a_i\times (suf_i-i)\times (mid-y_i)\),其中 \(suf_i\) 是比 \(i\) 大的下一个前缀最大值的下标,\(y_i\) 为最大的 \(j\in [l,mid]\) 使得 \(a_j>a_i\),若存在则令 \(j=l-1\)。
我们加入一个数 \(x\),不妨假设加入的是左边的,那么对于所有区间的最大值之和会有如下的修改:
- 将 \(x\) 左侧所有的后缀最大值的贡献删去。
- 将右侧所有 \(y_i\) 被影响的权值进行修改。
- 加入 \(x\) 的权值。
其中 1 和 3 可以被认为是单调栈上的操作,可以进行暴力修改,复杂度是 \(O(n)\)。现在的问题就是对于第二问,发现对于 \(y_i\) 的修改就是将所有 \(y_i\gets \max(y_i,x)\),那么也对于所有被弹出的 \(x'\),将 \(y_i=x'\) 的变成 \(x\)。我们将 \(y_i\) 相等的所有数合并成一个集合,那么就是进行若干的集合合并的操作,可以使用并查集直接维护。
这样单次的复杂度为 \(O(n\alpha(n))\),那么就有时间复杂度 \(T(n)=2T(\frac{1}{2}n)+O(n\alpha(n))\),有 \(T(n)=O(n\log n\alpha(n))\),可以通过。
T2 新生舞会
你说得对,但是 🤓👆。
这是一个公平组合游戏,所以我们考虑直接计算 \(\operatorname{SG}\) 函数。
如果这一次决策选择删掉的点是 \(x\),那么这个状态的 \(\operatorname{SG}\) 值就是 \(x\) 所有儿子,以及 \(x\) 及其所有祖先的兄弟的 \(\operatorname{SG}\) 值。
我们对于每一个节点维护其后继状态的 \(\operatorname{SG}\) 值的集合,发现 \(u\) 的集合就是对于其每一个儿子 \(v\) 的集合,将每一个数异或上 \(v\) 所有兄弟的 \(\operatorname{SG}\) 值之后,并在一起,然后加入所有儿子 \(\operatorname{SG}\) 值的异或和这个状态。
这个过程可以使用 01Trie 合并来实现,朴素实现的时间复杂度为 \(O(n\log n)\),空间复杂度为 \(O(n\log n)\)。
但是这题卡空间……
优化线段树合并形问题的空间的方法一般就两种:
- 写压缩线段树。
- 在优先遍历重儿子的情况下写节点回收。
这两种情况需要的节点数似乎都可以证明是 \(2n\) 左右量级的。
但是 dfs 有很大的空间尝试,仍然可能会导致 MLE,所以我们通过手写栈来代替 dfs 即可。
T3 PM 大师
不难发现会存在一个集合 \(S\),对于一个 \(a_y=0\) 的询问来说,如果它是序列中的第 \(k\) 个 \(0\),那么答案就是 \(S\) 中的第 \(k\) 小的元素。下面记 \(cnt_i\) 为 \(a_1,a_2\dots a_i\) 中 \(0\) 的数量。
我们考虑子任务 5,每一个数只会被加入一次。对于一个数 \(c\),我们只需要关注他最早一次出现的时间 \(pos_c\)。显然要有 \(\sum\limits_{x\in S}[x\le c]\ge cnt_{pos_c}\) 才可以,否则在到 \(pos_c\) 这一位之前,前面的 \(0\) 就已经填到了 \(c\),那么这里的 \(c\) 就没有意义了。
那么我们每一次加入的时候,判断如果删掉 \(c\),是否有 \(\sum\limits_{x\in S}[x\le c]-cnt_{pos_c}\ge 0\),但是注意到我们将 \(c\) 中 \(S\) 中删除之后,对于后缀那些已经加入的点来说,可能会导致它的 \(f_i=\sum\limits_{x\in S}[x\le i]-cnt_{pos_i}\) 减少 \(1\),从而 \(<0\),使得其需要重新加入 \(S\)。发现我们找到最小的 \(i>c\) 使得 \(f_i=0\) 即可。
我们可以使用线段树维护 \(f_i\),就可以支持区间加以及查找区间内最靠前的最小值。时间复杂度 \(O(n\log n)\)。
注意到加入只会对 \(S\) 造成 \(O(1)\) 的修改,所以删除也是可以维护的。
我们仿照 \(f_i\),对于所有 \(i\in S\) 且存在 \(a_j=i\) 维护 \(g_i=cnt_{pos_i}-\sum\limits_{j\in S}[j\le i]\) 即可。
时间复杂度仍然为 \(O(n\log n)\),可能有一定细节。
Day8(20241101)
本来以为 T2 有什么高论的,结果是我想多了。
T1 熟练
由于路径有很强的性质,可以通过多种方式证明答案就是被最多路径覆盖的节点被覆盖的次数。
现在考虑构造,对于链的情况,我们发现可以直接使用如下方式构造:从左到右扫描整条链,每当遇到一条路径时,给其分配一个没有节点占用的颜色,这条路径占用这个节点;当离开一条路劲时,将其占用的路径还原。由于不可能在同时占用所有的颜色的时候加入路径,所以无论何时有一定存在没有被占用的颜色。
考虑拓展到树上,先将所有的路径拆成 \(1\sim 2\) 祖先到后代的链,发现唯一的问题就是去遍历当前节点的儿子时,需要将当前节点对应的那些路径分配到对应的儿子那里。
考虑这个过程的逆过程就是将儿子合并,这是可以用线段树合并时间的,我们仿照线段树合并按照 dfn 序进行分裂即可。时间复杂度 \(O(n\log n)\)。
T2 皮鞋的多项式
发现就是要求子树的所有多项式的乘积的一段系数的和。
发现暴力维护每一个位置的 \(\prod\limits_{v\in T(u)} F_v(x)\) 是不现实的,所以考虑将每一个点 \(u\),维护 \(G_u(x)\times H_u(x)=\prod\limits_{v\in T(u)}F_v(x)\),其中有 \(H_u(x)\) 的项数 \(\le B\)。这样查询的时候,只需要遍历 \(H\) 中的每一个元素,对 \(G\) 查询区间和,可以使用前缀和差分来处理。
这样在合并的过程中,\(G\) 与 \(G\) 合并,\(H\) 与 \(H\) 合并,如果新的 \(H\) 的项数 \(>B\) 了,就将其放进 \(G\) 中。发现这样操作,本质不同的 \(G\) 只会有 \(O(\frac{n}{B})\) 中,对 \(G\) 使用 ntt 合并,复杂度为 \(O(\dfrac{n^2\log n}{B})\);对于 \(H\) 使用暴力卷积合并,根据树上背包的结论,复杂度为 \(O(nB)\)。取 \(B=O(\sqrt{n\log n})\) 得到最优复杂度 \(O(n\sqrt{n\log n})\)。
T3 幽默还是夢
Day9(20241103)
最后两个小时冲 T1 去了,结果 T1 这么不可做,直接倒闭了。
T1 游戏
T2 木桶效应
发现我们要统计 \(\sum\limits_{p}\prod\limits_{i=1}^n\min\limits_{j=1}^mp_{j,i}\),等价于求 \(\sum\limits_{p}\sum\limits_{x}[x_i\le p_{j,i}]\)。
交换枚举顺序,那么我们就变成了枚举数列 \(x\),统计有多少种排列方式使得 \(p\) 满足 \(x_i\le p_{j,i}\)。
先考虑 \(q=0\) 的情况,由于 \(x\) 越大限制越紧,可以考虑从大往小 DP:记 \(f_{i,j}\) 表示填了 \(x=n\sim {i+1}\),有 \(j\) 的位置的 \(x\) 确定了的方案数。
则有转移 \(f_{i-1,k}\gets f_{i,j}\times \left(\dfrac{(n-i-j+1)!}{(n-i-k+1)!}\right)^m\times \dbinom{k}{j}\)。时间复杂度 \(O(n^3)\)
对于 \(q\neq 0\),发现就是有 \(O(q)\) 行和列是特殊的,所以我们考虑对于这些行和列进行单独的处理。由此设计状态 \(f_{i,j,S}\) 表示填了 \(x=n\sim i+1\),有 \(j\) 个非特殊行已经确定了 \(x\),有 \(S\) 集合中的特殊行确定了 \(x\) 的方案数。
我们记有 \(cnt\) 个 \(g_{t,i,S}\) 表示第 \(t\) 个特殊列,在 \(n\sim i\) 中有多少个数被 \(\complement S\) 中的特殊行占用。
不难得到如下转移:\(f_{i-1,k,T}\gets f_{i,j,S}\times \left(\dfrac{(n-i-j-|S|+1)!}{(n-i-k-|T|+1)!}\right)^{m-cnt}\times \dbinom{k}{j}\times \prod\limits_{t=1}^{cnt}\dfrac{(n-j-g_{t,i,S}-i+1)!}{(n-k-|T|-g_{t,i,T}-i+1)!}\)。
暴力枚举 \(k,T\) 转移的复杂度为 \(O(n^33^q)\)。
发现转移的所有系数都可以拆成之和 \(S\) 与 \(T\) 有关的系数。所以在枚举 \(k\) 之后,可以直接使用高维前缀和进行转移,时间复杂度 \(O(n^32^qq)\)。
T3 月亮的背面是粉红色的
发现 \(f_t\) 是积性函数,有 \(f_t(\gcd(i,j))f_t(\operatorname{lcm}(i,j))=f_t(i)f_t(j)\),那么题目就是要求 \(\left(\sum\limits_{i=1}^nf_t(i)\right)^2\),也就是求 \(\sum\limits_{i=1}^nf_t(i)\)。
发现 \(\sum\limits_{i=1}^nf_t(i)=\sum\limits_{i=1}^ni^t\sum\limits_{d|i}[\text{不存在} p\neq 1 \text{使得} p^2|d]=\sum\limits_{i=1}^ni^t\sum\limits_{d|i}\sum\limits_{p^2|d}\mu(p)\)。
其等于 \(\sum\limits_{p=1}^{\sqrt{n}}\mu(p)\sum\limits_{p^2|d}\sum\limits_{d|i}i^t=\sum\limits_{p=1}^{\sqrt{n}}\mu(p)p^t\sum\limits_{d=1}^{\left\lfloor\frac{n}{p^2}\right\rfloor}d^t\sum\limits_{i=1}^{\left\lfloor\frac{n}{p^2d}\right\rfloor}i^t\)。其中 \(d(x)\) 为 \(x\) 的因数个数。
那么现在的问题就变成了求 \(\sum\limits_{ij\le \left\lfloor\frac{n}{p^2}\right\rfloor}i^tj^t\)。对于 \(\sum\limits_{ij\le n}i^tj^t\) 类型的问题显然是可以通过整除分块等方法做到 \(O(\sqrt{n})\)。那么直接套用此方法的时间复杂度为 \(\sum\limits_{p=1}^{\sqrt{n}}\sqrt{\dfrac{n}{p^2}}=\sqrt{n}\ln n\)。可以通过前 7 个 Subtask。
后两个 Subtask 似乎需要使用某个单次求解 \(O(n^{\frac{1}{3}}\operatorname{poly}(\log n))\) 的做法,然后就可以通过了。