思路
注意到 \(a+b=(a\operatorname{xor}b)+2\times(a\operatorname{and}b)\),其中 \((a\operatorname{xor}b)\) 可以理解为不进位加法,\(2\times(a\operatorname{and}b)\) 可以理解为加上进位的数。
于是将 \(s\) 与 \(x\) 带入得到 \(2\times(a\operatorname{and}b)=s-x\),因为 \(2\times(a\operatorname{and}b)\) 必定为一个非负整数,且为偶数,于是得到第一个无解条件:
- 当 \(s-x\) 为负数或奇数时,不存在合法的数对。
当 \(s-x\) 为偶数时,可以得到 \((a\operatorname{and}b)=\frac{s-x}{2}\),于是我们便知道了 \((a\operatorname{xor}b)\) 与 \((a\operatorname{and}b)\) 的值,下面对这两个数的二进制的每一位进行分类讨论:
- \((a\operatorname{xor}b)\) 和 \((a\operatorname{and}b)\) 的第 \(i\) 位均为 \(0\)。
此时根据 \((a\operatorname{xor}b)\) 可以知道 \(a,b\) 的第 \(i\) 位只能全为 \(0\) 或全为 \(1\),又因为 \((a\operatorname{and}b)\) 的第 \(i\) 位为 \(0\),所以 \(a,b\) 的第 \(i\) 位只能全为 \(0\)。
- \((a\operatorname{xor}b)\) 的第 \(i\) 位为 \(0\),\((a\operatorname{and}b)\) 的第 \(i\) 位为 \(1\)。
同理可得 \(a,b\) 的第 \(i\) 位均为 \(1\)。
- \((a\operatorname{xor}b)\) 的第 \(i\) 位为 \(1\),\((a\operatorname{and}b)\) 的第 \(i\) 位为 \(0\)。
此时 \(a,b\) 的第 \(i\) 位有两种选择(即 \((0,1)\) 或 \((1,0)\))。
- \((a\operatorname{xor}b)\) 和 \((a\operatorname{and}b)\) 的第 \(i\) 位均为 \(1\)。
当 \((a\operatorname{and}b)\) 的第 \(i\) 位为 \(1\) 时,\((a\operatorname{xor}b)\) 一定为 \(0\),则此时无解。
因为 \(a,b\) 均为正整数,则当 \(s=x\)(即 \((a\operatorname{and}b)=0\) 时),答案会包含 \(a=0\) 与 \(b=0\) 的情况,需要减去这两种情况。
总结
当 \(s-x\) 为负数或奇数或 \((a\operatorname{xor}b)\) 和 \((a\operatorname{and}b)\) 二进制下第 \(i\) 位均为 \(1\) 时,不存在合法的数对。
当 \((a\operatorname{xor}b)\) 的第 \(i\) 位为 \(1\),\((a\operatorname{and}b)\) 的第 \(i\) 位为 \(0\) 时,答案需要乘 \(2\)。
当 \(s=x\) 时,答案需要减 \(2\)。
代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
int s,x,ans=1;
signed main() {ios::sync_with_stdio(false);cin.tie(nullptr),cout.tie(nullptr);cin>>s>>x;if((s-x)&1ll||s-x<0)cout<<0;else{for(int i=63;i>=0;i--){if(!((((s-x)>>1ll)&(1ll<<i))!=0)&&(x&(1ll<<i)))ans*=2;if(((((s-x)>>1ll)&(1ll<<i))!=0)&&(x&(1ll<<i)))ans=0;}if(s==x) ans-=2;cout<<ans;}return 0;
}