[CodeForces] 1325D Ehab the Xorcist

我是研究僧i 提交于 2020-03-17 07:51:38

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 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();
    }

 

 

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!