原题链接
题目大意:
给定整数 u 和 v (0\(\leq\)u,v\(\leq\)\(10^{18}\) )试构造长度最短的数组,使得数组内所有元素的异或和为 u,加和为 v。
如果有解,输出两行,第一行输出一个整数 n,第二行输出 n 个非负整数,表示数组里的元素。多解输出任意一组即可。如果无解,输出一行一个整数 −1。
思路:
关于异或的一些性质
根据性质3和4,我们很容易得到
当
- u > v
- u 和 v 的奇偶性不一致
时,无解;
令d = v - u
if (d % 2 == 0), 根据性质1和2,我们很容易得到一组通解{u, \(\frac{d}{2}\), \(\frac{d}{2}\)};
因为序列要最短,所以需要判断一下{ u,d } 和 {u + \(\frac{d}{2}\), \(\frac{d}{2}\)} 符不符合条件;
if (d % 2 != 0), 则无解。
特殊的:若 u == v 则直接输出 u
AC代码
点击查看代码
#include <bits/stdc++.h>
#include <unordered_map>
#include <unordered_set>
#define xx first
#define yy second
#define IOS ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(0);
#define fixed fixed<<setprecision
#define endl '\n'
#define int long long
#define ll long long
#define pb push_back
#define db double
#define inf 0x3f3f3f3f
#define PII pair<int,int>
#define mem(x,y) memset(x,y,sizeof(x));
#define vi vector<int>
#define alls(x) x.begin(),x.end()
#define maxv *max_element
#define minv *min_element
#define NO cout << "NO" << '\n';
#define YES cout << "YES" << '\n';
#define rep(i,x,y) for(int i = (x); i <= (y); i ++)
#define dec(i,y,x) for(int i = (y); i >= (x); i --)
using namespace std;
priority_queue<int> pq;
priority_queue<int, vector<int>, greater<int> > up;
//---------------------------------------------------
int qmi(int a, int k, int p){ int res = 1 % p; while (k){ if (k & 1) res = res * a % p;
a = a * a % p;k >>= 1;} return res;}
int ksm(int a, int k){ int res = 1; while (k){ if (k & 1) res = res * a;
a = a * a;k >>= 1;} return res;}
//----------------------------------------------------
const int N1 = 1e6 + 10, mod = 1e9 + 7;
int fa[N1], infa[N1];
void initcp(int n){ fa[0] = infa[0] = 1; for (int i = 1; i < n; i ++ ) {
fa[i] = fa[i-1] * i % mod; infa[i] = infa[i-1] * qmi(i, mod - 2, mod) % mod;}}
int C(int a, int b){ if(a < b) return 0; return fa[a] * infa[a-b] % mod * infa[b] % mod;}
int CL(int a,int b){ if(a < b) return 0; int down = 1, up = 1;
for(int i = a, j = 1; j <= b; i -- ,j ++){ up = up * i % mod; down = down * j % mod;}
return up * qmi(down, mod-2, mod) % mod; }
int Lucas(int a, int b){ if(a < mod && b < mod) return C(a,b);
return Lucas(a/mod, b/mod) * C(a % mod, b % mod) % mod;}
int P(int a, int b){ if(a < b) return 0; return fa[a] * infa[a-b] % mod;}
/*-----------------------------------------------------------*/
const int N2 = 1e6 + 10;
int cntt, primes[N2];
bool stt[N2];
void initpr(int n){ for(int i = 2; i <= n; i ++){ if(!stt[i]) primes[cntt ++] = i;
for(int j = 0; primes[j] * i <= n; j ++){ stt[primes[j] * i] = true;
if(i % primes[j] == 0) break;} } }
int gcd(int a, int b){return b ? gcd(b, a % b) : a;}
// 返回末尾的1
int lowbit(int x){ return x & -x; }
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
//int dx[8] = {-1, -1, -1, 0, 1, 1, 1, 0};
//int dy[8] = {-1, 0, 1, 1, 1, 0, -1, -1};
/*----------------------------------------------------------*/
const int N = 1e6 + 10;
int a[N];
int n,m;
void solve()
{
cin >> n >> m;
if(n > m) {
cout << -1 << endl; return;
}
int aa = n % 2, bb = m % 2;
if(aa != bb)
{
cout << -1 << endl; return;
}
if(m == 0 && n == 0)
{
cout << 0 << endl; return;
}
int cc = m - n;
if(cc == 0)
{
cout << "1\n" << m << endl;
}
else if(cc % 2 == 0)
{
int d = cc / 2;
if( ((d + n)^d) == n)
{
cout << "2\n" << d+n << " " << d << endl;
}
else if( (cc^n) == n)
{
cout << "2\n" << n << " " << cc << endl;
}
else
{
cout << 3 << endl;
cout << n << " " << d << " " << d;
}
}
else
{
cout << -1 << endl;
}
}
signed main()
{
IOS
initcp(1010);
initpr(1010);
int asd = Lucas(110,12);
int sdf = CL(1010,120);
int dfg = ksm(34,9);
int T = 1;
//cin >> T;
while(T --)
{
solve();
}
return 0;
}