A - 打怪

为你打死毛球怪需要的回合数,那么有;

故你打死一只毛球怪会掉点血;

,说明你一只毛球怪都打不死;

,说明你能打死无限只;

否则,你只能打死只。

Code: 戳我看代码

B - 吃水果

对于一组询问(以下默认),有以下三种情况:

  • ,此时答案为
  • ,此时答案为。首先吃次,此时有,显然,,将翻倍后再吃次即可;总次数为
  • ,答案为的结果加。因为只要不断将翻倍,就必然会转变成上面两种情况之一。

只要根据上述内容递归处理即可,复杂度最坏情况下为

Code: 戳我看代码

C - 四个选项

首先,按照给出的个关系,将个题分组(假设分成了组);

然后,考虑,定义为前组、选A的题数为、选B的题数为、选C的题数为的方案数;

答案即为,注意选D的题数可以利用求出,不需要多开一维。

Code: 戳我看代码

D - 最短路变短了

定义为点出发到点的最短距离。

定义表示第条边的信息。

先对求出

因为,若第条边翻转会使最短路长度变短,则新的最短路必然是

所以,对于每个询问,若最短路长度变短,则

Code: 戳我看代码

  • Bonus: 若要判断第条边翻转后,最短路长度是否不变,只需把次短路也计算出来,分类讨论即可。

E - 相似的子串

考虑二分答案。

假设当前二分的

  • 先把所有长度为的子串的哈希值和起点位置组成二元组

  • 将所有二元组进行排序;

  • 按照的值分段,对每一段判断是否能取出个不相交的子串,这个利用two-pointer即可解决。

总复杂度

注意hash时要选择不常见的,不然容易被卡。

Code: 戳我看代码

F - 苹果树

离线+点分治。

为什么不写动态点分治?因为我不会。

将苹果记为形如的三元组,其中为苹果所在结点,为苹果的成熟度,为苹果出现的时间(对于原有的苹果,时间记为)。

将询问记为形如的四元组,其中为询问的原有定义,为询问的时间。

考虑分治的过程(假设分治中心为):

  • 将当前分治部分内的苹果按排序。

  • 将当前分治部分内的询问按排序。

  • 定义为成熟度为的苹果距离分治中心的最小距离(初始值定为)。

  • 利用扫描线的思路,枚举询问,利用所有出现时间小于询问时间的苹果来更新;然后更新枚举的询问的答案

  • 递归分治的每个子树。

利用线段树来维护,则总复杂度为

Code: 戳我看代码