• CF627A XOR Equation


    CF627A XOR Equation

    洛谷传送门

    题意翻译

    题目描述

    两个合法的整数 ab 的和为s,它们的按位异或和为x。请计算出所有可能的有序数对(a,b)的个数。

    输入格式

    输入共一行,包含两个整数s(2<=s<=1012)和x(2<=x<=1012)。

    输出格式

    输出一个整数,为合法的有序数对的个数。如果不存在合法的数对,则输出0。

    样例解释

    对于第一个样例,有以下合法的数对:(2,7) (3,6) (6,3) (7,2);

    对于第二个样例,有以下合法的数对:(1,2) (2,1)


    题解:

    首先,异或是不进位的加法。

    所以我们的目光就定位在“进位”这个位置。

    这时我们发现一个性质:(a+b=(a&b)<<1+(a ext{xor} b))

    也就是说,((s-x)>>1)就是((a&b))

    这时我们要把两种答案为0的情况拎出来:也就是(s-x)不能被2整除,或者s-x<0。

    然后我们开始逐位枚举(a&b)这个数。对于某一位为1的情况,显然a,b的对应位都要得1.那么这种情况,如果给出的x还限制这一位为1(不同)的话,那么就不合法。直接输出0.

    对于某一位为0的情况,显然(a,b)有(0,1)(1,0)和(0,0)三种抉择,那么这时如果x限制这一位为0,那只能是(0,0),如果x限制这一位为1,说明有两种可能,需要乘上2.

    需要说明的是,翻译有误。只能是正整数,不是它所说的整数。所以最后如果(a&b)=0的话,要减去2.

    AC代码:

    #include<cstdio>
    #define ll long long
    using namespace std;
    ll s,x,yu,ans;
    int main()
    {
    	scanf("%lld%lld",&s,&x);
    	ans=1;
    	yu=(s-x);
    	if(yu&1||s<x)
    	{
    		puts("0");
    		return 0;
    	}
    	yu>>=1;
    	for(int i=0;i<=60;i++)
    	{
    		if((yu>>i&1)&&(x>>i&1))
    		{
    			puts("0");
    			return 0;
    		}
    		if((!(yu>>i&1))&&(x>>i&1))
    			ans*=2;
    	}
    	if(!yu)
    		ans-=2;
    	printf("%lld
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    【leetcode】11. 盛最多水的容器
    【leetcode】8. 字符串转换整数 (atoi)
    【leetcode】6. Z 字形变换
    【leetcode】5. 最长回文子串
    【leetcode】LCP 19. 秋叶收藏集
    删除第一个节点问题
    问一个大学学习计算机这门专业的问题
    Struts文件上传页面上传后显示“连接已重置”
    2013-12-6 思杨没吃饱 饿醒了
    2013-12-7 snoopy乐园中的思杨
  • 原文地址:https://www.cnblogs.com/fusiwei/p/14032101.html
Copyright © 2020-2023  润新知