【APIO 2026】比赛 & 试题题解
GD-073,35+15+40=90。铁
比赛
开赛,发现 T1 是个 employ 状物,T2 是 adhoc,T3 是邻域+数据结构。
T1 想了一整场,最后一小时发现不太行了赶紧打了 T2 T3 暴力跑路。
- 启示:消除 adhoc 恐惧症。
T1 上升 ascend
容斥:\(\sum_a \prod_i ([f_i(a)=0]+[f_i(a)=1]w_i)\Rightarrow \sum_a \prod_i ([f_i(a)=0](1-w_i)+w_i)\)。
钦定下降的位置有 \(1-w_i\) 的贡献,没有钦定的位置贡献为 \(w_i\)。下降段有一个性质,每个段只会有不超过一个确定的元素。
设计 dp,一个一个位置填,同时我们肯定要考虑值域的情况。
不妨设前缀 max 为 \(v\),那么 \(v\) 所在段中 \(v\) 右侧的可以直接用组合数计算,所以我们需要计算 \(\le v\) 的数的个数。这样会涉及到大于 \(v\) 的数,我们需要确定这部分的相对顺序,才可以在两个前缀 max 之间转移。
所以状态设为 \(f_{i,c}\) 表示前 \(i\) 个数有 \(c\) 个 \(\le v\),方案数是多少。
那么枚举上一个分界点 \(j\),前缀 max 是 \(v'\),从 \(f_{j,c}\) 转移过来。则 \(q_{(j,i]}\) 内有不超过一个确定的元素。
- 若不存在确定的元素:枚举分界点 \(k\),\(q_{(j,k]}\) 大于 \(v\),\(q_{(k,i]}\) 小于等于 \(v\)。
- 转移系数:\(\binom{k-c}{k-j}\binom{v-c}{i-k}\),转移到 \(f_{i,c+i-k}\)。
- 存在确定的元素:即上述转移中 \(k\) 确定了,然后还要选出 \(q_{[1,j]}\) 中 \(\le v\) 的元素有几个,设为 \(x\)。
- 转移系数:\(\binom{v-v'}{x}\binom{k-c-x}{k-j}\binom{v-c-x-1}{i-k-1}\),转移到 \(f_{i,c+i-k+x}\)。
分步转移复杂度就是 \(O(n^3)\)。
T2 蛋糕 cake
subtask 1:加入 \(W,W+1,W+2,W+3,\cdots,W+100\),暴力询问。
subtask 2:加入 \(3,5\),查询 \(a_0+a_1\) 和 \(a_2\) 的大小关系。
subtask 3:倍增二分。
如果我们想要查询 \(x\) 和 \(2^i\) 的大小关系,我们可以加入 \(2^0\sim 2^{30}\),并询问 \(a_0+\cdots+a_{i-1}\) 和 \(a_i\) 的大小关系。
如果 \(x\ge 2^i\) 一定返回后者更大。这样可以给 \(x\) 减去 \(2^i\) 继续做。
然后是 \(x\) 和 1 比较大小,这需要多插入一个 1 然后问是否相等就好。
subtask 4:
二分并没有用到等于的性质。考虑到 \(3^K\ge W\),把返回值的信息利用完全。
加入 \(1,2,3,\cdots,W\),那么考察差分数组,我们要找到那个 0。
将差分数组平均分成三份,考虑其中两份,如果不相等那么 0 就在剩下那一份,否则递归这两份中的一个。
由于可能不是 3 的倍数,所以我们要用 \(W,W+1\) 来处理余数。
T3 集宝 gems
考虑 \(l=1,r=m\)。
令 \(S_i\) 表示 \((a_i,d_i)\) 构成的邻域。如果存在 \(S_{i}\cap S_{i+1}\ne \varnothing\),那么这两个邻域可以变为他们的交,走到的节点和距离都不变。
那么考虑每次找到最大的 \(r'\) 满足 \(R=\bigcap_{i=l}^{r'} S_i\ne \varnothing\),那么我们就可以走到 \(R\) 中距离 \(x\) 最近的节点。
然后是 \(R\cap S_{r'+1}=\varnothing\),所以我们要先走到 \(R\) 中距离 \(S_{r'+1}\) 最近的点,设这个点为 \(nxt_l\)。
那么递归 \(l\leftarrow r'+1,x\leftarrow nxt_l\) 就好。
现在面临的问题是:
- 邻域交的表示,以及找到邻域交到 \(x\) 最近的那个点。
- 预处理 \(f_i\) 表示 \(i\) 到 \(f_i\) 的邻域交非空。
- \(nxt_l\) 如何处理。
- 最后一段 \(f_i>r\),需要单独处理 \(R=\bigcap_{i=l}^{r} S_i\)。
邻域交:若有一个点 \(u\),现在判定是否都在邻域 \((o_i,r_i)\) 内。即判定是否有 \(\max_i dis(o_i,u)-r_i\le 0\)。
\(r_i\) 可以视作 \(o_i\) 上挂上一条边,那么只需要保留两个邻域即可求出最大值。那么判定交是否为空也是好做的。
到邻域交最近的点:距离为 \(\max(dis(u,o_1)-r_1,dis(u,o_2)-r_2)\),在邻域有交时必然可以取到。
找到这个点取在哪里可以通过树上 \(k\) 级祖先处理。
\(nxt_l\) 求解:类似上面,找到距离 \(a_{r'+1}\) 最近的点即可。
使用线段树维护区间邻域交查询,\(f_i\) 可以在线段树上二分。
需要维护:\(O(1)\) LCA,\(O(\log n)\) 树上 k 级祖先。
复杂度 \(O((m+q)\log m)\)。
浙公网安备 33010602011771号