首页 > 其他 > 详细

PKUSC2021部分题目简要题解

时间:2021-05-18 12:30:09      阅读:18      评论:0      收藏:0      [点我收藏+]

个人认为的难度排序:D1T1 < D2T1 < D2T2 < D1T2 < D2T3 < D1T3

两天的\(T1\)都是很简单的题,就不说了

D2T2代金券

  • 题意简述:有 \(n\) 道菜品,第 \(i\) 道菜品花费 \(a_i\). 可以使用价值 \(1\) 的消费券,初始时没有消费券。
    如果在一道花费 \(a\) 的菜品花费 \(b(b ≤ a)\)张消费券,则实际需要花
    \(a - b\) 元,并在用餐结束后获得 \(? \frac{a-b} {c} ?\) 张消费券。
    \(Q\) 次对序列 \(a_i\) 修改,每次修改结束后询问按照顺序品尝 \(n\) 个菜品
    的最小消费。

\(1 ≤ n, Q ≤ 3 × 10^5, 1 ≤ c ≤ 10^9, 1 ≤ ai ≤ 10^{12}\)

\(solution\)

  • 考试的时候只差一步了.....但还是没AC
  • 我们考虑这么一个贪心,首先我们注意令\(d_i = a_i \bmod c,b_i = a_i - d_i\),注意到对于任意一个物品,\(d_i\)使用消费券是一定不劣的,而\(b_i\)个物品如果消费券能留到后面就尽量留到后面
  • 所以我们有以下这么一个算法,每次购买\(b_i\),然后\(d_i\)个物品能用消费券就尽量用消费券,那么一定会存在一个后缀\(x\),使得\([x+1,n]\)的所有物品都可以使用消费券
  • 那么对于\(x\),我们可以直接二分出要买多少个物品
  • 如果是朴素的每次修改完遍历复杂度是\(O(n*q\log A)\)的,我考试也只想到这步
  • 注意到如果直接用数据结构维护这么一个过程是极其难以维护的,我们考虑继续观察性质,我们考虑一定会存在一个分界点,使得在那个分界点剩余的消费券等于\(0\),后面的都不等于\(0\),那么我们就可以直接维护,且可以发现最优的后缀一定在这个点后面,否则无法全部使用消费券,我们考虑如何找出这个点
  • 我们不妨将\(b_i,d_i\)看成括号匹配,那么问题就比较明朗了,我们令\(s_i = s_{i-1} + b_{i-1} + d_i\),那么\(s_i\)严格最小(若有多个最小点取最右边的)的点就是分界点(这个点消费券一定为\(0\),又因为后面的点都比它大,所以都不为\(0\))
  • 这个可以用线段树来维护,在找出这个分界点之后,我们可以直接计算前面使用了多少个消费券(因为为\(0\),所以前面所有产生的消费券都比使用了,即\(d_i\)的前缀和),后面的消费券(因为每次都有盈余,可以直接加加减减),那么我们又可以通过二分来得到\(x\)这个点,注意到\(x\)一定是满足以下条件最左边的点.
  • \(x\)的消费券不够后面用
  • \(x+1\)的消费券够后面用
  • 又因为由于\(x\)在分界点之后,消费券还剩多少可以直接计算,线段树上二分即可
  • 时间复杂度\(O((n + q) (\log A + \log n))\)

PKUSC2021部分题目简要题解

原文:https://www.cnblogs.com/y-dove/p/14779565.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!