【规律】Ehab the Xorcist

【题目链接】传送门

【题意】

  给出u,v,请找到一组数,使得  异或和=u,和=v。若不存在输出“-1”,如果有多组,输出最短的一组。

【题解】

  一开始我仅仅留意如何构造,没有留意题意中的最短。不过误打误撞发现一点规律。

  我们取最极端的例子就是u=v,我们可以把2进制下所有的位进行相加。

  u>v,必定是不存在。

  u<v,两者之间的差值,d=v-u。构造他们Xor=u,Sum=v,我们可以弄出来m = d / 2 ,

    u = u ^ m ^ m ,   v = u + m + m 

    a)根据这个条件,如果d为奇数必定不存在。(根据构造出来的条件)

    b)反面证明,如果d为奇数。我们考虑最小的位(bit)

      u^d_bit(0) != u_bit(0) ,我们对于d和u无论如果拆分,最低位都是不一致(即u为奇数,v为偶数,或者相反,反正最低位不一致)。

  通过a)和b)两种情况枚举后发现,u<v,有意义的一组仅有,d 为偶数时。

  u = v 时,答案就是“1  u”

  u < v 时,d =v-u为偶数时。m=d/2

  答案最长就是“3 u m m”,同时可能有u&m==0,此时答案就是“2 u^m m”


【具体代码】

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<vector>
 4 using namespace std;
 5 typedef long long ll;
 6 const int N = 100;
 7 vector<ll> Ans;
 8 int main()
 9 {
10     ll u , v ;
11     scanf("%lld%lld",&u,&v);
12     if( u == v && v == 0 ){
13         printf("0
");
14     }else if( u > v || ((v - u) & 1 )){
15         printf("-1
");
16     }else if( u == v ){
17         printf("1
%lld
",u);
18     }else{
19         ll t = ( v - u ) / 2 ;
20         if( (u & t) == 0 ){
21             printf("2
%lld %lld
",t,u^t);
22         }else{
23             printf("3
%lld %lld %lld
",u,t,t);
24         }
25     }
26     return 0 ;
27 }
View Code
原文地址:https://www.cnblogs.com/Osea/p/12564026.html