BZOJ4269再见Xor——高斯消元解线性基
题目描述
给定N个数,你可以在这些数中任意选一些数出来,每个数可以选任意多次,试求出你能选出的数的异或和的最大值和严格次大值。
输入
第一行一个正整数N。
接下来一行N个非负整数。
输出
一行,包含两个数,最大值和次大值。
样例输入
3
3 5 6
3 5 6
样例输出
6 5
提示
100% : N <= 100000, 保证N个数不全是0,而且在int范围内
求异或最大值和严格次大值,最大值直接用线性基求即可,因为用高斯消元求出的线性基直接将所有线性基异或在一起就是最大值,所以只需要把其中最小的一个线性基去掉就是次大值。
#include<set> #include<map> #include<queue> #include<stack> #include<cmath> #include<cstdio> #include<bitset> #include<vector> #include<cstring> #include<iostream> #include<algorithm> #define ll long long using namespace std; int n; int a[100010]; int tot; int ans; int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); } int i; for(i=1<<30;i;i>>=1) { int j; for(j=++tot;j<=n;j++) { if(a[j]&i) { swap(a[tot],a[j]); break; } } if(j>n) { tot--; continue; } for(j=1;j<=n;j++) { if(j!=tot&&a[j]&i) { a[j]^=a[tot]; } } } for(int i=1;i<tot;i++) { ans^=a[i]; } printf("%d %d\n",ans^a[tot],ans); }