Codeforces Round #681 (Div. 1, based on VK Cup 2019-2020

题解:
A. 考虑长度为(n-1)的差分数组,正数和要小于等于(a_1),负数和的相反数要小于等于(a_n).
B. 考虑将(a_i)改写为(k)如果(b_k=a_i),否则为(0).
(a=[1, 2, 3, 4, 5], b = [3, 2, 5]),可以改写成(a=[0,2,1,0,3]).
那么操作实际上就是对(a)里面的非零数按顺序考虑,每次删除相邻一个比它小的数.考虑完这个数后,那么它对后面的数和(0)是等价的,因此也可以看成删除它自己.
考虑相邻两个非零数([x,y]),如果(x>y)且有方案,那么(y)右侧一定有比它小的数,类似地递推下去,可以发现(x)右侧一定有一个(0).
因此方案数等于转换后数组里(每个非零数(与它相邻且比它小的数个数))之积.
C. 如果操作2次数比较小,那么可以直接对((i,j))求最短路,表示在第(i)个点并且已经经过(j)次操作(2)的最短路.
如果操作2次数比较大,那么它的影响会非常大,因此应该将操作2的次数作为第一关键字求最短路.
那么两个方向各求一次最短路后,考虑拼起来的最小值即可.
D. 假设有两个序列没有拿满,那么考虑最后一个数比较大的那个数,它多拿一个另外一个序列少拿一个,那么答案一定不会更差.
考虑枚举没有拿满的序列,那么每次复杂度是(O(NK))的,但是要枚举(N)次.
考虑线段树上分治,每次进入左儿子将右儿子的贡献加入到dp数组中,每次进入右儿子将左儿子的贡献加入到dp数组中.
这样做的复杂度是(O(NKlog N))的.

C感觉需要考虑的细节非常多,代码也比较复杂,会非常容易FST.
D是个经典模型,可惜没有先去想D.

原文地址:https://www.cnblogs.com/Heltion/p/13917392.html