BZOJ 4269: 再见Xor 线性基+贪心
Description
给定N个数,你可以在这些数中任意选一些数出来,每个数可以选任意多次,试求出你能选出的数的异或和的最大值和严格次大值。
Input
第一行一个正整数N。
接下来一行N个非负整数。
Output
一行,包含两个数,最大值和次大值。
最大值好办,次大值只需依次枚举线性基里的每一个元素,然后看异或哪个会变小就行.
#include <bits/stdc++.h> #define ll long long #define M 33 #define setIO(s) freopen(s".in","r",stdin) using namespace std; int n,m; ll d[M*10]; void insert(ll x) { if(!x) return; for(int i=M;i>=0;--i) { if(x&(1ll<<i)) { if(d[i]) x^=d[i]; else { d[i]=x,++m; break; } } } } int main() { int i,j; // setIO("input"); scanf("%d",&n); for(i=1;i<=n;++i) { ll a; scanf("%lld",&a),insert(a); } ll qmax=0, qmin=0; for(i=M;i>=0;--i) if(d[i] && (qmax^d[i]) > qmax) qmax^=d[i]; qmin=qmax; for(i=0;i<=M;++i) if(d[i] && (qmin^d[i]) < qmin) { qmin^=d[i]; break; } printf("%lld %lld\n",qmax,m>1?qmin:0); return 0; }