starrycoding周赛
E题:题意:给定一个数组,你有两个操作,第一个操作是对任意前缀减去一个数,第二个操作是对任意后缀减去一个数。现在希望你用这两个操作将这两个数都变成0,要求操作次数最少,无解情况需要判断。
Sol:考虑两种操作,一种前缀操作,一种后缀操作都是对一整个区间操作,我们应该想到区间加常用的差分!我们记d为差分数组
-
操作1等价于
-
操作2等价于
题目要求我们用最少操作次数完成原数组恰好全部置0,等价于差分数组变0.
问题转化到这逐渐清晰。
-
考虑d[n+1]是不影响答案的,也就是操作二使用没有代价,对于差分数组中的所有正元素全部可以免费变0
-
对于为0的不用管
-
对于负元素,我们需要用操作1将其变0,考虑代价是次数加1以及d[1]减小,如果d[1]不够减,则原问题无解。
1 | void solve(){ |
C题:有n个数每次取出最大的数x,算它的bitsum(x),然后x-=bitsum(x),这样反复k次,求第k次取出的数的bitsum.
Sol:由于k的范围最大到1e9,所以我们很难用优先队列去模拟这个过程,注意到初始的数值域只有1e6,我们考虑维护一个桶统计每个值出现的次数,从大到小遍历,次数累加到转移的数上面,直到k不够减。注意特判k过大的情况,直接输出0.
1 | int cal(int x){ |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 爱飞鱼的blog!
