2022OI集训营提高组第二场题解
T1 技能
sol1
预处理每一个起点到每一个终点的距离,暴力枚举哪一个起点到哪一个终点。
时间复杂度
能拿
正解
显然,从贪心角度考虑,对于每一棵子树,肯定是子树内的起点和终点优先匹配,匹配不了的再到子树外去匹配。
可以证明,子树内匹配肯定比子树内外匹配更优。
那么我们就可以直接得出,对于每一条边,它被账号便利的次数肯定是子树内起点与终点数量之差。
直接对于每一条边,统计答案就可以。
因为
最大到
,所以我们需要写一个高精。
只需要高精乘低精和高精度加法,直接数组模拟就可以了。
时间复杂度是
。
可以证明,子树内匹配肯定比子树内外匹配更优。
那么我们就可以直接得出,对于每一条边,它被账号便利的次数肯定是子树内起点与终点数量之差。
直接对于每一条边,统计答案就可以。
因为
只需要高精乘低精和高精度加法,直接数组模拟就可以了。
时间复杂度是
T2 奶茶代金券
考虑到两个大于贪心思路应该是优先将大的和小的匹配进行购买,如果匹配结束后还有多余的“小的”,那么将“小的”之间两两匹配;如果匹配结束之后还有多余的“大的”,那么无法继续匹配。
考虑大的和小的进行匹配的过程,恰好小于
最终思路:将所有“小的”从大到小排序,然后开始匹配,匹配的时候将所有“大的”从小到大进行匹配,类似双指针维护匹配过程。
最终再判断是否还有多余的“小的”,将这些“小的”两两匹配。(随便怎么匹配都是一样的)
T3 帮助
sol1
暴力枚举两个人,看第一个人会不会帮助第二个人。
如果会帮的话直接帮。
时间复杂度
,可以拿
分。
如果会帮的话直接帮。
时间复杂度
sol2
所有显然对于每一个人,要么他不愿意帮助任何一个人,要么他愿意帮助所有人。
要么他愿意接受所有人的帮助,要么不愿意接受任何一个人的帮助。
所以对于每一个,直接看他会不会帮助其他人,愿不愿意接受其他人的帮助。
直接统计答案就可以。
时间复杂度
注意,从这里以后的算法,都要特判一下,存不存在某个人帮助了自己的情况。
sol3
首先我们可以对
显然,如果
如果
然后我们可以预处理一个数组
显然,我们只需要预处理
然后对于每一个人
时间复杂度
sol4
和上面差不多。
预处理一个
有值的
第
时间复杂度
sol5
没有
我们首先将所有人按照成绩,升序排序。
那么对于每一个人,他愿意帮助的人(在排序之后)一定是一个区间。
并且我们可以直接使用二分,求出他愿意帮助的人是哪一个区间。
然后维护答案的差分序列,最后前缀和即可。
时间复杂度
所有暴力就好啦,一共能拿
sol6
还是这是另一个做法,和正解更靠近一些。
还是先将所有人按照成绩,升序排序。
还是用二分求出每一个人,愿意帮助哪一个区间。
我们再维护一个
容易发现
你还可以发现,在递推的过程中,
我们这样就可以一边递推
时间复杂度一样,是
正解
和前面一样的排序,二分。差不多的套路,维护
和上面的一样,所有的
还是一样,可以在计算答案过程中计算出
最后统计答案的时候,求的就是
所以我们先离散化,然后使用树状数组递推
时间复杂度还是
T4 神奇的变换
一句话题意:给你一个序列和若干个询问,每次询问给出一个区间,求出这个区间所有数字乘起来之后,莫比乌斯函数值,约数个数,约数和。约定:为了方便计算时间复杂度,后文将
sol1
你可以按照题面进行模拟。
时间复杂度
sol2
首先我们知道肯定不能先求出
考虑有什么东西,可以代替这个序列,计算出答案。
我们发现,假如可以求出,每一个质数,在这个区间内的出现次数,同样可以把答案算出来。
所以我们先筛出
最后,对于每一个询问,暴力便利区间,并统计出现的质数,计算答案。
时间复杂度是
为啥是
第一个是因为,每一个数字,最多可能会有
第二个是因为,每一次计算贡献的时候,肯定是先把原来(统计的这个质数)的贡献除掉,然后再乘上新的贡献,这里我们需要预处理逆元。
感觉有点卡。
所以我们可以提前预处理逆元。
因为我们是知道所有质数出现次数的,假如一个质数出现了
时间复杂度是
可以拿
sol3
感觉和sol2的思路差不多。
因为所有
预处理
询问的时候暴力枚举
时间复杂度
能拿
sol4
不难发现,我们只需要线性筛,就可以知道
随便选一个大一点的质数当作模数,然后对这个序列做前缀积,直接逆元就可以了。
时间复杂度
能拿
暴力分一共
正解
个人感觉和sol3关系比较大。首先我们会发现一个很不错的性质:序列中的每一个数字,最多只“包含”一个大于
而正好,小于等于
也就是说,我们要解决的,就只是大于
考虑对序列进行分块,块长为
我们再预处理另一个数组
我们还可以预处理一个数字
这个数组的话,直接枚举起点,然后一个一个加数字。
然后再来看统计答案。
首先对于一个询问的区间
对于中间的所有整块,我们已经知道了答案(
然后对于两边的散块,我们直接一个一个数字加进去并且更新答案就可以了。
时间复杂度是