AtCoder Regular Contest 119 游记

都是神仙思维题啊…… dblark 七分钟 B 题, 六分钟 C 写完 C

A

找出三元组 (a,b,c)(a, b, c) 满足 a×2b+c=na \times 2^b + c = n 使 a+b+ca+b+c 最小。

k=n2bk = \frac{n}{2^b},那么三元组可以有 (k,b,c),(k1,b,c+2b),(k, b, c), (k-1, b, c+2^b), \dots 因为 2b12^b \ge 1, 所以让 kk 变小没有好处,那么枚举一个 bb 然后求出 aacc 即可。

B

每次可以 01111110011\dots1 \to 111\dots 0 或反过来,问最少需要多少步使 SS 变成 TT

显然若 SSTT11 的个数不一样是没有办法做到的,而一样的显然是可以完成的。

然后我就陷入了没有进展的一个小时,一会儿考虑整块 11 的跳动,一会而又想贪心处理哪一些 11 应该到哪些位置去。

终于过了一个多小时之后才发现了关键:考虑 00 的位移。

本质上这个变换所需要的最少步数就是把移动所涉及到的 00 都给移动一次。所以问题变成了如何判断哪些 00 是必需移动的就可以了。

那么显然左右的 0011 个数都相等的直接就不需要移动了。

C

同样是思维题。

每次可以把相邻的两个同时加或减一个数,问能全变成 00 的区间有几个。

因为相邻的两个同时加减,所以奇数位和偶数位的差是不变的,那么一开始奇数偶数位的差不一样的肯定不行,一样的直接考虑把前面尽可能清空就可以了。

有个小 trick, 可以前缀和的时候直接对奇偶位和的差作前缀和就行了,然后存进个 std::map 里面,统计的时候看有几个一样的中间选俩就可以了。


又掉分了。