这是一道简单的数论(贪心)题
题目大意:
- 对于非负整数数列:
a 1 , a 2 , a 3 . . . . . . a n a_1,a_2,a_3......a_n a1,a2,a3......an
将其划分为 M M M组,使其异或和最小。
解题思路:
我们考虑一对二进制数
a
=
(
10011
)
2
a=(10011)_2
a=(10011)2和
b
=
(
11001
)
2
b=(11001)_2
b=(11001)2.异或运算的性质为:
1
x
o
r
1
=
0
1\space xor \space 1=0
1 xor 1=0
0
x
o
r
0
=
0
0\space xor \space 0=0
0 xor 0=0
1
x
o
r
0
=
1
1\space xor \space 0=1
1 xor 0=1
0
x
o
r
1
=
1
0 \space xor \space 1=1
0 xor 1=1
若我们将
a
a
a和
b
b
b 求异或,得到:
a
n
s
1
=
a
x
o
r
b
=
(
01110
)
2
ans_1=a \space xor \space b=(01110)_2
ans1=a xor b=(01110)2
而若我们将其合成同一组则:
a
n
s
2
=
a
+
b
=
(
101100
)
2
ans_2=a+b=(101100)_2
ans2=a+b=(101100)2
显然有
a
n
s
1
<
a
n
s
2
ans_1< ans_2
ans1<ans2
实际上,根据异或的运算规律,有:
∀
a
,
b
∈
R
∗
,
a
x
o
r
b
≤
a
+
b
\forall a,b\in\mathbb R^*,a\space xor \space b\leq a+b
∀a,b∈R∗,a xor b≤a+b
所以我们根本就不用分组,全部异或起来就好啦!
代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
int x;
cin>>n;
cin>>x;
for(int i=1;i<n;i++)
{
int y;
cin>>y;
x^=y;
}
cout<<x<<endl;
return 0;
}