码迷,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 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
迷上了代码!