20260106 省选模拟赛
20260106 省选模拟赛
https://htoj.com.cn/cpp/oj/contest/detail?cid=22618738769920
Problem B. 压力测试
对于 \(k=n\) 的情况,我们对异或拆位考虑,最外层枚举第 \(w\) 位,然后把 \(a_i\) 变为 \(01\)。里面再长剖即可。
加上 \(k\) 的限制,似乎需要向上再套一个维护前缀的数据结构,但复杂度不可接受。
拆位时,\(2^w\) 个 \(1\) 接上 \(2^w\) 个 \(0\) 的结构非常优美,但我们的长剖没有利用到。换为倍增,设 \(f_{x,i}\) 为所有深度在 \([dep_x,dep_x+2^i)\) 内且 dfn 序在 \(low_x\) 之前的点的答案 (较新奇的处理方法),处理其他信息倍增即可。
设 \(pre_x\) 为与 \(x\) 深度相同的节点中最后一个 dfn 序小于 \(x\) 的节点,那么询问时回答 \(Calc(x,k)-Calc(pre_x,k)\) 即可。
Problem C. 数据
考虑选出一个子集,判断其是否合法。设第 \(j\) 个选出来的位置是 \(i\),则要满足 \(i\ge 2j+1\)。
所以我们两个两个考虑,维护一个小根堆,压进两个,弹出一个。留在小根堆里的就是答案。
计数不好记录堆里元素。将 \(b_i\) 拆为 \(\sum_{w\ge 1}[b_i\ge w]\),最外层枚举一个 \(w\),只需知道堆里有几个 \(1\) 即可。
设 \(f_{i,j}\) 为考虑前 \(i\) 个,堆里有 \(j\) 个 \(1\),转移讨论 \(b_i\) 是否 \(\ge w\) 即可。复杂度 \(O(mn^2)\)。
然后发现答案是关于 \(w\)、以 \(a_i\) 为断点的 分段多项式,每一段进行插值,\(O(n^4)\)。
进一步发现,\(a_i\) 单调递增,枚举最后一个 \(a_i<w\),前半部分转移系数为 \(0,a_i\),后半部分为 \(a_i-w+1,w-1\)。前半部分是个前缀积,后半部分对任意的分界点都相同,所以不需要分段了,\(O(n^3)\)。

浙公网安备 33010602011771号