Description
给定N个数,你可以在这些数中任意选一些数出来,每个数可以选任意多次,试求出你能选出的数的异或和的最大值和严格次大值。
Input
第一行一个正整数N。
接下来一行N个非负整数。
Output
一行,包含两个数,最大值和次大值。
Sample Input
3
3 5 6
Sample Output
6 5
HINT
100% : N <= 100000, 保证N个数不全是0,而且在int范围内
分析:
选二次相当于没选,所以每个数只有选和不选。
直接线性基。
最大值就是线性基的异或和,次大值就是除了最小的基之外的异或和。
代码:
/**************************************************************
Problem: 4269
User: ypxrain
Language: C++
Result: Accepted
Time:228 ms
Memory:1288 kb
****************************************************************/
#include <iostream>
#include <cstdio>
const int maxp=30;
using namespace std;
int n,x;
int a[maxp+7],bit[maxp+7];
void ins(int x)
{
int c=0;
for (int i=maxp;i>=0;i--)
{
if (bit[i]&x)
{
if ((!a[i]) && (!c)) c=i;
x^=a[i];
}
}
if (!x) return;
a[c]=x;
for (int i=0;i<=maxp;i++)
{
if (i==c) continue;
if (a[i]&bit[c]) a[i]^=x;
}
}
void calc()
{
int ret=0;
for (int i=maxp;i>=0;i--) ret^=a[i];
printf("%d ",ret);
for (int i=0;i<=maxp;i++)
{
if (a[i])
{
printf("%d",ret^a[i]);
return;
}
}
}
int main()
{
bit[0]=1;
for (int i=1;i<=maxp;i++) bit[i]=bit[i-1]*2;
scanf("%d",&n);
for (int i=1;i<=n;i++)
{
scanf("%d",&x);
ins(x);
}
calc();
}