【CF】【位运算】【数学】C. XOR Equation
问题描述
\(a+b=m\),a xor b = n , 求点对(a,b)的个数
异或运算相当于是一种模2的加法运算,即在某位上,a和b同时为1时,是不将进位的效果纳入考虑的。
因而有公式,\(a+b = a\space xor\space b + (a \& b)\times 2\)
于是我们可以得到a与上b的结果,进而,若a与上b的结果在某一位上为1的话,那么就说明a和b在这个位置上的数字都为1。
进一步地,我们对a xor b 上的每一个位置进行考虑
若a xor b 在这个位置上的结果为1的话,则说明a和b两者之间其中有一者在这个位置上为1,另一者在这个位置上为0。而它们与起来的结果就为0。所以若与起来的结果不为0的话,则说明矛盾,此时应该直接输出0。
若a xor b在这个位置上的结果为0的话,则说明 a = b,且 a & a = a,所以a = b = a & b,此时答案也是固定的。
所以答案为2的a xor b中1的个数的次数方(又由于a!=0,b!=0,此时应该进行特判,而出现0的情况,只有每一位位置上要么满足\(a_i\space xor\space b_i = 1\),或者满足当a_i xor b_i = 0时,\(a_i = b_i = 0\),总的来说\(a \& b = 0\) ,即\(a + b = a\space xor\space b\))
#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define MAX 1000005
#define MOD 1000000007
using namespace std;
const int N = 3E5+5,M = 6E5+10;
ll sum,xorn;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>sum>>xorn;
if((sum-xorn)%2) return puts("0");
ll p = (sum-xorn)/2;
ll ans = 1;
for(int i=45;i>=0;i--)
{
int pxor = (xorn>>i) & 1;
int pp = (p>>i) & 1;
if(pxor==1)
{
if(pp==1)
return puts("0");
else ans *= 2;
}
}
if(sum==xorn) ans -= 2;
cout<<ans;
return 0;
}