Codeforces Round 829

CF1753

A1/A2

不难。考虑计算出整个序列的和,如果小于0就全序列取相反数转成正的(容易证明这样做是等价的)。

然后你对目前的 \(sum\),如果是奇数显然无解,否则对于一个还没有选的 \(1\),将其和前面一个数配对,这时 \(sum\) 会减小 \(2\),做到 \(sum\) 归零即可后面全部分成一个数的区间。有无 \(0\) 没有影响。

B

考虑将阶乘合并。\(i\)\((i-1)!\) 可以合成一个 \(i!\),你只需要看最后合出来的有没有剩下比 \(x!\) 小的阶乘即可。

C

考虑将序列分成两块,前面一块大小是 \(0\) 的个数,即我们要把所有 \(0\) 都丢到这里面,剩下的 \(1\) 丢到后面。那么 \(0\) 的个数是 \(cnt\),在前面块的 \(1\) 的个数是 \(x\),则你期望经过 \(\frac{cnt\times (n-cnt)}{x^2}\) 次操作会将一个前面的 \(1\) 移到后面。于是你枚举剩下几个,加起来即可。

D

有一个结论,每张床最多操作一次。好像比较不对劲,也不太能猜,但其实能证。

因为你每次只需要把一个空位置挪到一个你希望的位置(如果同时出现两个相邻空位置那就做完了,如果不在一起那么两个是独立的(进行黑白染色,答案的格子必然在黑白格)),那么首先不可能同一个操作做两次(移动操作那就出现相邻空位,旋转操作则要么无意义,要么会出现相邻空位,要么你尝试以两次旋转代替移动操作时,发现第一次旋转或者不旋转就提供了需要的空位)。

那么你就可以对于一个位置能够转换到的位置加边跑最短路,当然你需要黑白格各跑一遍,取相邻两个黑白格分别到最优空位的最小代价作为答案。

最短路需要建立超级源点向所有黑/白空位连边权为 0 的边跑最短路。实现上不必建出超级源点,只需要将所有空位的距离置为 0 然后全丢到小根堆里跑 dij 即可。

posted @ 2022-10-26 15:19  infinities  阅读(16)  评论(0编辑  收藏  举报