蓝书板刷记录

记录刷蓝书的想法。

ACWing 101-150

101. 最高的牛

条件的本质是 AB 间的所有数都小于他们俩,所以每次相当于把 AB 间所有数都 -1。可以这样做的原因是题目中给的区间必然两两不相交(如果出现则无解)。

115. 给树染色

考虑贪心:显然每次选可扩展的最大点是错误的,但发现树中权值最大的点一定会在它的父节点染色后被马上染色。想到可以使用一种等效权值的思想来维护每个点的大小,具体是这样的:假设有权值为 \(x,y,z\) 的三个点,已知 \(x,y\) 是连续染色的。发现先染 \(x,y\) 的代价是 \(x+2y+3z\),先染 \(z\) 的代价是 \(z+2x+3y\)。由于我们只关心他们间的相对大小关系,所以可以加上 \(\frac{z-y}{2}\),现在就可以看做权值为 \(\frac{x+y}{2}\)\(z\) 的两个点的染色问题。故每次在当前点中找到等效权值最大的点合并。\(n\le1000\) 可以直接 \(O(n^2)\)

123. 士兵

横纵坐标可以独立考虑:对于纵坐标,显然取中位数时结果最小;对于横坐标,考虑延续 CF713C 和 P2893 的思想,排序后让每个数 -i 再取中位数。

127. 任务

发现 x 值如果更大,那么做这个任务一定更优(因为值域被降维打击了),考虑贪心。先将所有任务和机器按照 x 从大到小的顺序排序,然后枚举任务,把 x 值不小于当前任务 x 值的机器的 y 值丢进一个 multiset 里,这样每次查询的时候可以直接在里面找不小于当前任务 y 值的最小 y 值。为什么这样做是对的?因为被丢进 multiset 里面的所有机器都是没有用的,而且 x 值都满足限制,所以可以只用考虑 y 值(即这些机器的 x 值对后面的任务来说已经没有意义了)。

133. 蚯蚓

性质:当 \(x_1\ge x_2\) 时,这两个数新生成的数仍然是满足 \(x_1\) 生成的数不小于 \(x_2\) 生成的对应的数。所以可以开 3 个队列分别存原有的,新生成的形如 \(\lfloor px\rfloor\) 的和形如 \(x - \lfloor px\rfloor\) 的蚯蚓。每次在队头取出最大的即可。

134. 双端队列

正着做不好做,考虑把所有数排序之后分配到每个队列里。因为我们依次处理每个元素,所以每个双端队列中的数在原数组中的下标形成单峰序列,排序直接贪心。

ACWing 301-350

331. 干草堆

感觉自己想不到(笑

题意:给定长度为 \(n\) 的数组 \(a\),要求将这些数分成按顺序分成尽量多组,要求每一组的和都比前一组的和小。

正着做不太行,因为不好确定当组的和应当多大才够。所以可以反转一下序列,反过来考虑,让当前组大于上一组的情况下尽量小。

定义 \(g(i)\) 表示考虑前 \(i\) 个数,末一组和的最小值,\(f(i)\) 表示其组数。令 \(s(i)=\sum\limits_{j=1}^ia_j\),转移就是 \(g(i)=\min\limits_{0\le j<i,g(j)\le s(i)-s(j))}\{s(i)-s(j)\}\)。由于 \(s(i)-s(j)\)\(j\) 增加而减小,可以倒序枚举 \(j\),最大的满足条件的 \(j\) 即为最优。这样的复杂度是 \(O(n^2)\) 的,随机数据下表现优异,然而可以被这样卡掉:

n = 100000
print(n)
for i in range(n - 1):
    print(1)
print(10000)

考虑优化。判断条件是 \(g(j)\le s(i)-s(j)\),也就是 \(g(j)+s(j)\le s(i)\)。可以把 \(g(j)+s(j)\) 丢到值域线段树上 \(O(n\log n)\) 二分,也可以维护一个 \(j\)\(g(j)+s(j)\) 都单调递增的单调队列:在队首如果有 \(j_1<j_2\) 都满足条件,因为 \(s(i)\) 随着 \(i\) 增加而增加,前者就不如后者;在队尾如果有 \(j_1<j_2\) 满足 \(g(j_1)+s(j_1)\ge g(j_2)+s(j_2)\),那么前者也不如后者。

\(O(n\log n)\)here

\(O(n)\)here

posted @ 2023-02-15 09:25  xx019  阅读(43)  评论(0)    收藏  举报