• 「CF1325D Ehab the Xorcist」


    题目大意

    给出 (u)(v)两个数,需要构造出最短的且异或和为 (u),和为 (v) 的序列.

    分析

    (分析均在二进制下)

    先考虑不存在的情况,可以发现如果 (u>v) 显然是不存在的,在考虑每加入一个新的数,如果是奇数,那么异或和最后一位会异或上 (1),和的最后一位也会异或上 (1),如果加的偶数则最后后一位不会变化,所以必须 (u)(v) 奇偶性相同时才会有答案.

    (下面的分析中有一个很重要的结论:(forall a in mathbb{Z} exists a oplus a=0))

    如果 (u)(0),如果 (v) 也是 (0),则直接输出 (0),否则 (v) 一定是偶数,所以可以将它拆成两个 (frac{v}{2}).

    如果 (u) 不为 (0),考虑拆成三个数 (u,frac{v-u}{2},frac{v-u}{2}),三个数的和为 (v),且三个数为异或和为 (u),但是这并不意味着一定是三个数,如果 ((u+frac{v-u}{2})oplus frac{v-u}{2}=u) 时就只要两个数了,其实也就是 (u)(frac{v-u}{2}) 不存在在同一个位置为 (1).

    代码

    #include <bits/stdc++.h>
    #define REP(i,first,last) for(int i=first;i<=last;++i)
    #define DOW(i,first,last) for(int i=first;i>=last;--i)
    using namespace std;
    long long u,v;
    int main()//代码没什么好说的
    {
    	scanf("%lld%lld",&u,&v);
    	if(u>v||(v-u)&1)
    	{
    		return 0&printf("-1
    ");
    	}
    	if(!u)
    	{
    		if(!v)
    		{
    			return 0&printf("%lld
    ",u);
    		}
    		return 0&printf("2
    %lld %lld
    ",v/2,v/2);
    	}
    	if(u==v)
    	{
    		return 0&printf("1
    %lld",u);
    	}
    	if(u&((v-u)/2))
    	{
    		return 0&printf("3
    %lld %lld %lld",u,(v-u)/2,(v-u)/2);
    	}
    	return 0&printf("2
    %lld %lld",u+(v-u)/2,(v-u)/2);
    }
    
    
  • 相关阅读:
    利用Oracle分析函数row_number和sys_connect_by_path实现多行数据合并为一行
    public string err属性
    table冻结表头和列[转]
    转:Js日期操作
    ASP.NET中JSON的序列化和反序列化
    javascript Date format(js日期格式化) [转]
    刚开通的博客
    调用图片
    散记兼容,需要整理
    ie6、div高度低于字体大小、则继承fontsize
  • 原文地址:https://www.cnblogs.com/Sxy_Limit/p/12496202.html
Copyright © 2020-2023  润新知