首页 > 代码库 > CodeForces 635C XOR Equation

CodeForces 635C XOR Equation

位运算。

又涨姿势了:$a + b = (aXORb) + 2*(aANDb)$,$ (aXORb)$是不进位的部分,$2*(aANDb)$为进位之后的部分,相加就是$a + b$。

知道了这个转换,这题就很容易了。设$n=a+b$,$m=(aXORb)$,$x=(aAND b)$;$n$、$m$和$x$都是已知的。

题目要求统计有多少$(a,b)$满足:

$\left\{ {\begin{array}{*{20}{c}}
{a + b = n}\\
{aXORb = m}
\end{array}} \right.$

等价于统计有多少$(a,b)$满足:

$\left\{ {\begin{array}{*{20}{c}}
{aAND b = x}\\
{aXORb = m}
\end{array}} \right.$

因此,可以按位统计,然后乘法原理乘一下就得到了答案。如果$n=m$,答案还需要减$2$,因为多统计了$0$ $n$和$n$ $0$。

#pragma comment(linker, "/STACK:1024000000,1024000000")#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#include<vector>#include<map>#include<set>#include<queue>#include<stack>#include<bitset>#include<iostream>using namespace std;typedef long long LL;const double pi=acos(-1.0),eps=1e-6;void File(){    freopen("D:\\in.txt","r",stdin);    freopen("D:\\out.txt","w",stdout);}template <class T>inline void read(T &x){    char c=getchar(); x=0;    while(!isdigit(c)) c=getchar();    while(isdigit(c)) {x=x*10+c-0; c=getchar();}}LL n,m,ans=1;LL b[50],c[50];int main(){    cin>>n>>m;    if(m>n) { printf("0\n"); return 0; }    if((n-m)%2!=0) { printf("0\n"); return 0; }    b[0]=1; for(int i=1;i<=40;i++) b[i]=2*b[i-1];    LL x=(n-m)/2;    for(int i=0;i<=40;i++)    {        for(int s1=0;s1<=1;s1++)        {            for(int s2=0;s2<=1;s2++)            {                LL f1,f2;                if((m&b[i])) f1=1; else f1=0;                if((x&b[i])) f2=1; else f2=0;                if((s1^s2)!=f1) continue;                if((s1&s2)!=f2) continue;                c[i]++;            }        }    }        for(int i=0;i<=40;i++) ans=ans*c[i];    if(n==m) ans=ans-2;        cout<<ans<<endl;        return 0;}

 

CodeForces 635C XOR Equation