这是一个nim游戏,先手必胜的策略也是非常显然的:
A
1
x
o
r
A
2
.
.
.
x
o
r
A
n
≠
0
A_1 xorA_2...xorA_n \neq 0
A1xorA2...xorAn=0
这样如果后手必胜则移动后的
A
1
′
x
o
r
A
2
′
=
A
3
x
o
r
A
4
x
o
r
A
5
.
.
.
A
n
A'_1 xorA'_2=A_3 xorA_4xorA_5...A_n
A1′xorA2′=A3xorA4xorA5...An
设
x
=
A
3
x
o
r
A
4
x
o
r
A
5
.
.
.
A
n
,
A
1
=
y
,
A
2
=
z
,
A
1
′
=
a
,
A
2
′
=
b
x=A_3 xorA_4xorA_5...A_n,A_1=y,A_2=z,A'_1=a,A'_2=b
x=A3xorA4xorA5...An,A1=y,A2=z,A1′=a,A2′=b
所以我们需要找到满足条件的a,b:
a
+
b
=
y
+
z
,
a
x
o
r
b
=
x
,
a
≤
y
,
a
>
0
a+b=y+z,a xorb=x,a\leq y,a >0
a+b=y+z,axorb=x,a≤y,a>0
其中a最小是多少。
由于
a
x
o
r
b
=
a
+
b
−
2
(
a
A
N
D
b
)
axorb=a+b-2(aANDb)
axorb=a+b−2(aANDb)
注以下的xor用^表示,and用&表示
所以上面的式子推一下就可以发现:a^b=x=a+b-2(a&b)
⇒
\Rightarrow
⇒a&b=
a
+
b
−
x
2
\frac{a+b-x}{2}
2a+b−x,所以如果a+b-x是奇数答案不存在。
如果我们有了a&b的值,则a和b中的某一些位置就固定了下来。由于我们知道a+b的值,所以a和b中剩余(不在a&b中)的位的和等于a+b-2*(a&b)由于不存在进位所以贪心分配就ok了。
code
#include<bits/stdc++.h>
#define rb(a,b,c) for(int a=b;a<=c;++a)
#define rl(a,b,c) for(int a=b;a>=c;--a)
#define LL long long
#define IT iterator
#define PB push_back
#define II(a,b) make_pair(a,b)
#define FIR first
#define SEC second
#define FREO freopen("check.out","w",stdout)
#define rep(a,b) for(int a=0;a<b;++a)
#define KEEP while(1)
#define SRAND mt19937 rng(chrono::steady_clock::now().time_since_epoch().count())
#define random(a) rng()%a
#define ALL(a) a.begin(),a.end()
#define POB pop_back
#define ff fflush(stdout)
#define fastio ios::sync_with_stdio(false)
#define debug_pair(A) cerr<<A.FIR<<" "<<A.SEC<<endl;
#define biggest(A,B) A=max(A,B)
#define smallest(A,B) A=min(A,B)
using namespace std;
const int INF=0x3f3f3f3f;
typedef pair<int,int> mp;
typedef pair<mp,mp> superpair;
int n;
LL a[303];
int main(){
fastio;
cin>>n;
rb(i,1,n)
cin>>a[i];
LL tmp=0;
// a xor b = a+b - 2*(a and b)
rb(i,3,n){
tmp^=a[i];
}
LL need=a[1]+a[2]-tmp;
if(need<0||need%2==1){
cout<<"-1"<<endl;
return 0;
}
LL sum=a[1]+a[2];
LL rest=a[1]+a[2]-need;
need/=2;
LL upp=a[1];
a[1]=need;
a[2]=need;
rl(i,42,0){
if(need&(1ll<<i)){
if(rest&(1ll<<i)) {
cout<<-1<<endl;
return 0;
}
continue;
}
if(rest&(1ll<<i)){
if(a[1]+(1ll<<i)<=upp){
a[1]+=1ll<<i;
}
else{
a[2]+=1ll<<i;
}
}
}
if(a[1]==0||a[2]>=sum||a[1]>upp){
cout<<-1<<endl;
return 0;
}
cout<<upp-a[1]<<endl;
return 0;
}