A
按 升序排序。
首先可以发现把删边变成加边。
因此每个点至少被加 次。
考虑每次合并 联通块。
这样代价为 ,且最小。
B
注意到 在
进制下为
。
于是直接输出 即可。
特殊情况:如果 或
且
,则无解。
C
我们考虑每个数 ,的贡献,不难发现,对一个区间
有贡献当且仅当
或者
中
的数的个数
(这里比较时可以用
二元组进行比较)。
我们套路地令 ,那么问题转化为求有多少包含
的区间
的区间和
。从大到小枚举
,那么每次就是在
中把一个位置从
变为
。那么我们只需要找到
对应的
的位置
,向前找
个
,向后也找
个
,得到一个下标序列
。枚举
表示左端点
,此时
的范围也是一个区间,累计贡献即可。
使用 STL set 即可 维护上述过程。std 使用了链表以减小常数。
D
记录 表示
的前缀和。
令 。
转化为求 的
。
等价于 。
两边加 :
。
等价于 。
也就是说, 区间内恰好有一个数不被吸引!记这个数的位置为
。
我们做以下解法:枚举 ,倒序枚举本质不同的
,也就是
的
,枚举
个
即可,这么做的正确性在于若存在
个本质不同的
使得
是可以取得答案的右端点中最靠右的一个,需要满足该处答案相对于右端点在
处的减小量大于
中的任意一处,抵消掉公共部分后可得:
(考虑右端点从
变化到
的过程,至少花费了
的代价)。进而归纳得到
。
F
发现图上这样的询问是困难的,考虑使用莫队状物。
对于区间的扩展,连续扩展 次可以直接 BFS 做到
的复杂度。即每次扩展时直接遍历能到达的未经过的所有点,均摊地维护当前集合的价值。
考虑据此利用区间随机生成的性质,尝试将所有询问区间划分为若干组,使得每组中第 个区间包含第
个区间,那么对于每组询问,我们容易以
的时间复杂度解决。
考察如下的方式确定每个区间所属的组。若 全部为
,我们直接将区间按右端点递增,在此基础上左端点递减排序,从左到右对每个区间,考虑将这个区间和目前能代表一个组的区间中,被它包含的区间中左端点最靠左的区间划归同一组,并用这个区间代表这一组。这一过程与随机数列上升子序列划分是相似的,由经典结论得组数应是
级别的。猫树分治式的执行这一过程,总组数仍然应是
级别的。
事实上。不进行猫树分治,直接进行这一过程,总组数仍为 级别的。可以发现,相比于猫树分治,直接进行这一过程不会劣。
这一过程可以使用 set 或树状数组维护。是经典问题,不做赘述。
有一些可能复杂度更优,速度也更快的做法,但出题人不会证明复杂度。