洛谷P8540 - 一道数学诈骗题

文章讨论了一个关于二进制运算的问题,特别是涉及异或操作和低位1的计算。当对一个数进行平方并异或另一个数的操作时,通过分析数的奇偶性和二进制表示,可以确定最后的低位1的位数,即lowbit。对于偶数次幂的情况,可以通过二项式定理简化计算,最终得出lowbit的值与原始数的低位1有关。
摘要由CSDN通过智能技术生成

传送门

文中加粗部分是需要读者稍微思考一下原因的地方 (不是重点)


题意已经说得很清楚了,这里不再赘述。

先考虑一下样例二,将 1 0 18 10^{18} 1018 化成二进制: 1101...001000000000000000000 1101...001000000000000000000 1101...001000000000000000000

其实只需要知道末尾有 18 18 18 0 0 0 就行了,因为在 x x x 变为 x 2 c x^{2c} x2c 时,后面 18 18 18 0 0 0 就会变成 18 × 2 c 18\times 2c 18×2c 0 0 0,如果再异或 c c c,就相当于把末尾的几位变成 c c c,此时除了末尾上的 c c c x 2 c ⊕ c x^{2c}\oplus c x2cc 的前面部分的数已经不会影响结果了(因为最后求 lowbit ⁡ \operatorname{lowbit} lowbit 就只关心末几位的值)。所以每做一次操作,末几位都是 c c c,那么最后的 lowbit ⁡ \operatorname{lowbit} lowbit 就是 lowbit ⁡ ( c ) \operatorname{lowbit}(c) lowbit(c)

再扩展到一般情况:

  • c c c 是偶数, a a a 是奇数,那么二进制中的最后一位就始终都是 1 1 1,所以最后的 lowbit ⁡ \operatorname{lowbit} lowbit 就是 1 1 1

  • c c c 是偶数, a a a 是偶数,这个就和样例二差不多: a a a 的二进制末尾至少有一个 0 0 0 a 2 c a^{2c} a2c 的末尾就至少有 2 c 2c 2c 0 0 0,肯定比 c c c 的二进制的位数多,异或 c c c 就相当于把末尾的几位变成 c c c,又因为 c c c 是偶数,所以 a 2 c ⊕ c a^{2c}\oplus c a2cc 的末尾也至少有一个 0 0 0,又变成了开始的情况,只不过末几位是 c c c 而不是 a a a。一直推下去,最后的 lowbit ⁡ \operatorname{lowbit} lowbit 就是 lowbit ⁡ ( c ) \operatorname{lowbit}(c) lowbit(c)

  • c c c 是奇数,此时根据 a a a 的奇偶又分成两种情况:

    • a a a 是偶数,和前面一样: a 2 c a^{2c} a2c 的末尾至少有 2 c 2c 2c 0 0 0,异或 c c c 就相当于把末尾的几位变成 c c c,因为我们只关心末几位,所以就可以把原数看成 c c c
    • a a a 是奇数,那么 a 2 c a^{2c} a2c 也是奇数,因为 c c c 也是奇数,奇数异或奇数就变成了偶数,然后又变成了上一个情况,即奇偶交替。
    • 如果最后的数是个奇数,那么 lowbit ⁡ \operatorname{lowbit} lowbit 就是 1 1 1
    • 如果最后是个偶数,那么就要考虑倒数第二步。因为 b > 1 b>1 b>1,所以倒数第二步的数的二进制末尾一定是 c c c,那么最后答案就相当于 lowbit ⁡ ( c 2 c ⊕ c ) \operatorname{lowbit}(c^{2c}\oplus c) lowbit(c2cc)

其实做到这就已经做完了,但是 lowbit ⁡ ( c 2 c ⊕ c ) \operatorname{lowbit}(c^{2c}\oplus c) lowbit(c2cc) 还可以化简一下。

考虑用二项式定理展开 c 2 c c^{2c} c2c

c 2 c = ( c − 1 + 1 ) 2 c = ∑ i = 0 2 c C 2 c i × ( c − 1 ) i = 1 + 2 c ( c − 1 ) + C 2 c 2 × ( c − 1 ) 2 + . . . + ( c − 1 ) 2 c c^{2c}=(c-1+1)^{2c}=\sum_{i=0}^{2c} C_{2c}^{i}\times (c-1)^i=1+2c(c-1)+C_{2c}^{2}\times (c-1)^2+...+(c-1)^{2c} c2c=(c1+1)2c=i=02cC2ci×(c1)i=1+2c(c1)+C2c2×(c1)2+...+(c1)2c

我们将上式所有项按 lowbit ⁡ \operatorname{lowbit} lowbit 大小来排序,最小的两项当然是 1 1 1 2 c ( c − 1 ) 2c(c-1) 2c(c1),因为 c − 1 c-1 c1 是偶数,所以 lowbit ⁡ ( 2 c ( c − 1 ) ) = lowbit ⁡ ( c − 1 ) × 2 \operatorname{lowbit}(2c(c-1))=\operatorname{lowbit}(c-1)\times 2 lowbit(2c(c1))=lowbit(c1)×2

从第三项开始,所有项的 lowbit ⁡ \operatorname{lowbit} lowbit 都不小于 lowbit ⁡ ( c − 1 ) × 2 \operatorname{lowbit}(c-1)\times 2 lowbit(c1)×2,所以 c 2 c c^{2c} c2c 一定可以被表示为 k × lowbit ⁡ ( 2 ( c − 1 ) ) + 1 k\times \operatorname{lowbit}(2(c-1))+1 k×lowbit(2(c1))+1,其中 k ∈ N + k\in N^+ kN+

形象点,把 c 2 c c^{2c} c2c c c c 的二进制分别表示出来(随便一个例子,只需要看后五位):

c 2 c c^{2c} c2c 1101...1010001 1101...1010001 1101...1010001

c c c    1010...0101001 \ \ 1010...0101001   1010...0101001

可以发现,最末尾的 1 1 1 会抵消,但倒数第二位不会,所以 lowbit ⁡ ( c 2 c ⊕ c ) = lowbit ⁡ ( c − 1 ) \operatorname{lowbit}(c^{2c}\oplus c)=\operatorname{lowbit}(c-1) lowbit(c2cc)=lowbit(c1)

#include <iostream>
#include <cstdio>
#define ll long long
using namespace std;
ll a,b,c;
ll lb(ll x){return x&-x;}
int main()
{
    cin >> a >> b >> c;
    if(c&1)
    {
        if((a&1)^(b&1))cout << 1; //ab不同奇偶,那么最后答案就是奇数
        else cout << lb(c-1); //ab同奇偶,最后答案就是偶数
    }
    else cout << ((a&1)?1:lb(c));
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值