1 条题解
-
0
自动搬运
来自洛谷,原作者为

szh_AK_all
S挂分挂到被洛谷7级勾卡线|I can do all things搬运于
2025-08-24 21:15:54,当前版本为作者最后更新于2023-12-26 12:53:16,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
出题人题解。
分析
我们有一个数 ,如要使 在二进制下从右往左数的第 位为 ,则需判断这一位是否为 ,如果是,则无需进行任何操作,否则, 会改变,操作数也会改变。
举个例子:考虑 在二进制下的第 位是否为 。 在二进制下表示为 ,第二位为 。可以发现,一个数在二进制下的第 位是否为 与最高位到第 位无关,所以,我们要取出这个数的第 位到第 位。
如何取出这个数的第 位到第 位呢?只需要这个数对 取模即可。因为,这个数在二进制下的第 位到第 位一定小于 ,而最高位到第 位一定是 的倍数。同上面的例子一样, 对 取模,得到 ,也就是二进制下的 ;
假设令 在二进制下的第 为 需要 至少加上 ,那么 就是操作数。由于操作数要尽可能小,那么我们需要让 在二进制下的第 到第 为的值为 。举个例子,若要使一个数在二进制下的第 位为 ,只需让这个数在二进制下的第 到第 位在二进制下表示为 。如果表示为 则不是最优操作。所以,在最优情况下,操作数为
如果 在二进制下的第 位本身就是 ,那么取出的第 到第 位肯定大于或等于 ,所以在计算操作数时将 与 取个最大值即可。 局部代码如下:
lg[0] = 1; for (int i = 1; i <= 32; i++) lg[i] = lg[i - 1] * 2; ... int k; cin >> k; if (lg[k - 1] > (n % lg[k])) { ans += lg[k - 1] - (n % lg[k]); n += lg[k - 1] - (n % lg[k]); }
- 1
信息
- ID
- 9510
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 2
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者