D:Ehab the Xorcist

或许更好的阅读体验

Ehab the Xorcist

思路

刚看时确实是一脸懵,最怕的就是这种构造题了,然后细想好像能写啊。

判断不可行的条件,只有两种情况:

  • 一、 v < u v < u 是一定不可能的,一串数的异或值一定小于其数串的和。
  • 二、当u是奇数时,数串中一定存在奇数个奇数,所以整体的和一定是奇数;当u时偶数时,如果存在奇数,那么一定是偶数个奇数,所以整体的和一定是偶数。

到了这里两种不可行的情况就考虑完了, n接下来我们考虑可行的方案:

  • 假设 v = = u v == u ,当 v = 0 v = 0 的时候直接输出0,当 v ! = 0 v != 0 的时候,就是"1\nv\n",即可。
  • 我们考虑下一种情况的最小串的情况:我们约定temp = (u - v) >> 1,一定可以构造出 t e m p t e m p v temp | temp | v 是符合要求的。但是我们要考虑其值最小,我们想想还有没有可能得到 n = 2 n = 2 的情况,当然是存在的,当 v & t e m p = = 0 v \& temp == 0 的时候,我们显然可以构造出 v + t e m p t e m p v + temp | temp 也是符合条件的。

代码

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

inline ll read() {
    ll f = 1, x = 0;
    char c = getchar();
    while(c < '0' || c > '9') {
        if(c == '-') f = -1;
        c = getchar();
    } 
    while(c >= '0' && c <= '9') {
        x = (x << 1) + (x << 3) + (c ^ 48);
        c = getchar();
    }
    return f * x;
}

int main() {
    // freopen("in.txt", "r", stdin);
    // freopen("out.txt", "w", stdout);
    ios::sync_with_stdio(false);
    ll u = read(), v = read();
    if(((u & 1) == (v & 1)) && (v >= u)) {
        if(u == v) {
            if(!u)  puts("0");
            else cout << "1\n" << u << "\n";
        }
        else {
            ll temp = v - u >> 1;
            if((temp & u) == 0)
                cout << "2\n" << u + temp << " " << temp << "\n";
            else cout << "3\n" << u << " " << temp << " " << temp << "\n";
        }
    }
    else    puts("-1");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_45483201/article/details/106628830