码迷,mamicode.com
首页 > 其他好文 > 详细

[CodeForces] 1325D Ehab the Xorcist

时间:2020-03-17 08:26:52      阅读:63      评论:0      收藏:0      [点我收藏+]

标签:www   into   -o   without   otherwise   contains   cal   ase   private   

Given 2 integers u and v, find the shortest array such that bitwise-xor of its elements is u, and the sum of its elements is v.

Input

The only line contains 2 integers u and v (0≤??,??≤10^18).

Output

If there‘s no array that satisfies the condition, print "-1". Otherwise:

The first line should contain one integer, n, representing the length of the desired array. The next line should contain n positive integers, the array itself. If there are multiple possible answers, print any.

 

First, let‘s consider a few special cases. 

Xor is basically bitwise-add ignoring carries. This means if such a shortest array exists, u should never be bigger than v. 

If the LSB of u must be the same with the LSB of v, i.e, u and v have the same parity(u % 2 == v % 2) for such an array to exist. Either we have odd number of 1s on LSB, which leads to a LSB 1 on v or we have even number of 1s on LSB, which leads to a LSB 0 on v.

If u and v are both 0, then we only need an empty array; If u and v are the same but not zero, then we only need a single element array with u.

 

Now let‘s consider the general case. Let x = (v - u) / 2, then [u, x, x] meets the problem condition. Here we applied the xor property: d ^ d = 0.  d ^ 0 = d. This means the longest array that we ever need to consider is 3. So we just need to check if array of length 2 is possible. Pick two numbers a and b, they need to satisfy: a ^ b = u, a + b = v.  

The following statement holds for any a and b.

a + b = a ^ b + 2 * (a & b)

a & b = ((a + b) - a ^ b) / 2 = (v - u) / 2 = x.  For any bit of x that is 1, the corresponding bit of a and b must also be 1. This means the corresponding bit of u must be 0. If the kth bit in x is 0, then as long as at least one of a[k] and b[k] is 0, we‘re good. This puts no restriction on u[k]. Summarizing, as long as x & u == 0, a and b exist. Otherwise, there is no array of length 2 that meets the stated conditions. When x & u == 0, u + x == u ^ x, merge [u, x, x] into [u + x, x] and we have u ^ x ^ x = (u + x) ^ x.

 

Why is a + b = a ^ b + 2 * (a & b) true? 

a ^ b is add without considering the carries. So in order to get a + b from a ^ b we need to take the missing carry part into account. When does carry happen? Exactly when a[k] == b[k] = 1. So we basically left out 2 equal part of indices where a[i] == b[i] = 1, which is exacly 2 * (a & b).

 

 

    private static void solve(int q, FastScanner in, PrintWriter out) {
        for (int qq = 0; qq < q; qq++) {
            long u = in.nextLong(), v = in.nextLong();
            if(u > v || u % 2 != v % 2) {
                out.println(-1);
            }
            else if(u == v) {
                if(u == 0) {
                    out.println(0);
                }
                else {
                    out.println(1);
                    out.println(u);
                }
            }
            else {
                long d = (v - u) / 2;
                if((u & d) != 0) {
                    out.println(3);
                    out.println(u + " " + d + " " + d);
                }
                else {
                    out.println(2);
                    out.println((u + d) + " " + d);
                }
            }
        }
        out.close();
    }

 

 

 

[CodeForces] 1325D Ehab the Xorcist

标签:www   into   -o   without   otherwise   contains   cal   ase   private   

原文地址:https://www.cnblogs.com/lz87/p/12508373.html

踩
(0)
赞
(0)
   
举报
评论 一句话评论(0)
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!