Description
给定N个数,你可以在这些数中任意选一些数出来,每个数可以选任意多次,试求出你能选出的数的异或和的最大值和严格次大值。
Input
第一行一个正整数N。
接下来一行N个非负整数。
Output
一行,包含两个数,最大值和次大值。
Sample Input
3
3 5 6
Sample Output
6 5
HINT
100% : N <= 100000, 保证N个数不全是0,而且在int范围内
Source
裸的线性基.我之前没学过所以来感受一下.
求完线性基,最大值就是异或和,次大值就把最小的那个再异或一遍除掉.
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define P 10086
#define MAXN 100010
#define GET (ch>='0'&&ch<='9')
using namespace std;
int n,a[MAXN];
int ans;
void in(int &x)
{
char ch=getchar();x=0;
while (!GET) ch=getchar();
while (GET) x=x*10+ch-'0',ch=getchar();
}
int gauss()
{
int i,j,k=0;
for (i=1<<30;i;i>>=1)
{
for (j=k+1;j<=n;j++)
if (a[j]&i) break;
if (j==n+1) continue;swap(a[++k],a[j]);
for (j=1;j<=n;j++)
if (j!=k&&(a[j]&i)) a[j]^=a[k];
}
return k;
}
int main()
{
in(n);int size;
for (int i=1;i<=n;i++) in(a[i]);
size=gauss();
for (int i=1;i<=size;i++) ans^=a[i];
printf("%d %d\n",ans,ans^a[size]);
}