题目链接:https://codeforces.ml/contest/1325/problem/D
题意:给你两个正整数
u
u
u和
v
v
v,让你找个正整数序列
a
[
]
a[]
a[],使的
a
[
1
]
+
a
[
2
]
+
.
.
.
+
a
[
n
]
=
v
a[1]+a[2]+...+a[n] = v
a[1]+a[2]+...+a[n]=v且
a
[
1
]
⨁
a
[
2
]
⨁
.
.
.
⨁
a
[
n
]
=
u
a[1]\bigoplus a[2]\bigoplus ... \bigoplus a[n] = u
a[1]⨁a[2]⨁...⨁a[n]=u
思路:首先考虑几个特殊情况:
1)、
v
≥
u
v\geq u
v≥u才有解,因为
a
+
b
=
a
⨁
b
+
2
×
(
a
&
b
)
a + b = a\bigoplus b + 2\times (a \& b)
a+b=a⨁b+2×(a&b);
2)、
u
=
v
u = v
u=v且
u
=
0
u = 0
u=0时,答案就是一个
0
0
0(最后一个样例);
3)、
u
=
v
u = v
u=v但
u
≠
0
u \neq 0
u=0时,答案为
{
u
}
\{u\}
{u};
接下来我们考虑除了这几个特判之外的情况。
我们令
x
=
v
−
u
2
x = \frac{v-u}{2}
x=2v−u,那么序列
{
u
,
x
,
x
}
\{u,x,x\}
{u,x,x}一定是答案,
因为
u
+
x
+
x
=
v
,
u
⨁
x
⨁
x
=
u
u+x+x = v,u\bigoplus x\bigoplus x = u
u+x+x=v,u⨁x⨁x=u
又因为我们要求一个正整数序列,所以
4)、
v
−
u
v - u
v−u不是二的倍数时,无解。
所以我们现在只需要考虑有没有什么样的数对
a
,
b
a,b
a,b,满足
a
+
b
=
v
a+b = v
a+b=v且
a
⨁
b
=
u
a\bigoplus b = u
a⨁b=u还是考虑上面说的公式
a
+
b
=
a
⨁
b
+
2
×
(
a
&
b
)
a + b = a\bigoplus b + 2\times (a \& b)
a+b=a⨁b+2×(a&b),那么我们可以得到
v
=
u
+
2
×
(
a
&
b
)
v = u + 2\times(a\&b)
v=u+2×(a&b),这样我们化简一下,可以得到
a
&
b
=
v
−
u
2
=
x
a\&b = \frac{v-u}{2} = x
a&b=2v−u=x
因为
a
⨁
b
=
u
a\bigoplus b = u
a⨁b=u且
a
&
b
=
x
a\&b = x
a&b=x,所以我们可以对
a
a
a和
b
b
b一位一位的进行分析,如果(一下
a
a
a和
b
b
b表示
a
a
a和
b
b
b的某一位二进制位)
a
=
1
&
&
b
=
1
−
>
u
=
0
,
x
=
1
a = 1 \&\& b = 1 -> u = 0,x = 1
a=1&&b=1−>u=0,x=1
a
=
1
&
&
b
=
0
−
>
u
=
1
,
x
=
0
a = 1\&\&b=0->u=1,x=0
a=1&&b=0−>u=1,x=0
a
=
0
&
&
b
=
1
−
>
u
=
1
,
x
=
0
a = 0\&\&b=1->u=1,x=0
a=0&&b=1−>u=1,x=0
a
=
0
&
&
b
=
0
−
>
u
=
0
,
x
=
0
a = 0\&\&b=0->u=0,x=0
a=0&&b=0−>u=0,x=0
所以如果
a
,
b
a,b
a,b有解,那么
u
&
x
=
0
−
>
u
+
x
=
u
⨁
x
u\&x = 0->u+x = u\bigoplus x
u&x=0−>u+x=u⨁x,那么此时数列
{
u
+
x
,
u
}
\{u+x,u\}
{u+x,u}是符合题意的,因为
u
+
x
+
x
=
v
,
(
u
+
x
)
⨁
x
=
(
u
⨁
x
)
⨁
x
=
u
u+x+x = v,(u+x)\bigoplus x = (u\bigoplus x)\bigoplus x = u
u+x+x=v,(u+x)⨁x=(u⨁x)⨁x=u
所以这一题总结一下就是:
1)、
v
≤
u
v\leq u
v≤u时无解;
2)、
u
=
v
u = v
u=v且
u
=
0
u = 0
u=0时,答案就是一个
0
0
0(最后一个样例);
3)、
u
=
v
u = v
u=v但
u
≠
0
u \neq 0
u=0时,答案为
{
u
}
\{u\}
{u};
4)、
v
−
u
v - u
v−u不是二的倍数时,无解;
5)、
u
&
x
=
0
u\&x = 0
u&x=0时,解为
{
u
+
x
,
u
}
\{u+x,u\}
{u+x,u};
6)、
u
&
x
≠
0
u\&x\neq 0
u&x=0时,解为
{
u
,
x
,
x
}
\{u,x,x\}
{u,x,x};
细节好多
这样我们就可以写代码啦:
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <cmath>
#include <vector>
#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define LL long long
#define pii pair<int,int>
#define sd(x) scanf("%d",&x)
#define slld(x) scanf("%lld",&x)
#define pd(x) printf("%d\n",x)
#define plld(x) printf("%lld\n",&x)
#define rep(i,a,b) for(int i = a ; i <= b ; i++)
#define per(i,a,b) for(int i = b ; i >= a ; i--)
#define mem(a) memset(a,0,sizeof(a))
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
#define fast_io ios::sync_with_stdio(false)
const LL INF = 1e12;
const LL mod = 1e9 + 7;
const int maxn = 2e5 + 7;
int out[maxn];
int u[maxn],v[maxn];
int main() {
LL u,v;
while(~scanf("%lld%lld",&u,&v)) {
if(u > v || (v > u && ((v - u) & 1LL))) pd(-1);
else if(u == v) {
if(u == 0) printf("0\n");
else printf("1\n%lld\n",u);
} else {
LL x = (v - u) / 2LL;
if((u & x) == 0) {
printf("2\n%lld %lld\n",u + x,x);
} else {
printf("3\n%lld %lld %lld\n",u,(v-u)/2LL,(v-u)/2LL);
}
}
}
return 0;
}