这是一道简单的数论(贪心)题
题目大意:
- 对于非负整数数列:
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;
}