讲题人讲义(D,F,G)

D 又是一年毕业季

F 自爆机器人

结论:一段长度为n的区间,它的子区间长度设子区间长度为len_i

那么不同len_i的数量不会超过\sqrt n

\sum_i len_i = n,不同的len_i 都取尽可能小,设为len_i = i,有$1 +2 + \dots + m = n\$

可得\frac {m * (m + 1)} {2} = nm \le \sqrt n

思路:

将路径拆解成两部分——从0n的必要路线,在任意两个墙壁来回走的路线

如果t < n的话显然不可能炸到怪物

除去0n的必要路线需要花费n的时间外,还剩t-n的时间可以在两个墙壁来回走

将两个墙壁来回走的路线拆解成只在相邻墙壁来回走的路线x_1 \iff x_3可以变成x_1\iff x_2 + x_2 \iff x_3

对于设d_i = x_i - x_{i - 1},设每两个墙壁间走k_i

可得\sum d_i * k_i \le t - n

使用完全背包求解,d_i的种类不会超过\sqrt n,时间复杂度可通过结论证明为O((t - n)\sqrt n)

G 大鱼吃小鱼

发现题目给的时间段是左闭右开联想到差分操作

对时间段离散化,用差分表示在l_i时刻加入第i条鱼,第r_i时刻消失第i条鱼,用前缀和维护第i时刻有哪些鱼

枚举时刻i,求第i时刻开吃的话最大能到多大的体重。对体重离散化,然后用树状数组维护离散化后体重为w的鱼的实际总重量

维护操作:

  • 第条鱼加入时有(是离散化后体重为的鱼原本的体重)
  • 第条鱼消失时有

设当前体重为weight(同样被离散化),查询在i时刻第一条体重大于weight的鱼的离散化体重w,然后吃掉在这之间的所有鱼weight += query(weight, w - 1)。如不存在体重大于weight的鱼,那么可以把这一时刻所有的鱼都吃掉

如果吃完后体重\ge w的话,那么继续迭代操作

如果吃完后体重<w,已经不可能吃掉这条鱼了,退出迭代,此时是i时刻能到达的最大体重

因为每次可以吃掉体重自身的鱼后,都相当于至少对之前的体重*2,所以体重增长速度是指数级别的,最多只会遇到\log (\max a_i)次比自身体重大的鱼

查询第i时刻第一条体重大于weight操作——用multiset维护当前有哪些体重的鱼(体重为实际体重),用内置upperbound函数\log n求出体重大于mp_{weight}的鱼

时间复杂度O(n\log n \log(\max a_i))

全部评论

相关推荐

10-13 16:58
门头沟学院 Java
点赞 评论 收藏
分享
10-29 18:20
济南大学 Java
用微笑面对困难:他不是人事吗,怎么净特么不干人事
点赞 评论 收藏
分享
评论
2
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务