1. 程式人生 > >bzoj4269 再見Xor 線性基

bzoj4269 再見Xor 線性基

Description


給定N個數,你可以在這些數中任意選一些數出來,每個數可以選任意多次,試求出你能選出的數的異或和的最大值和嚴格次大值。

100% : N <= 100000, 保證N個數不全是0,而且在int範圍內

Solution


線性基應用。。
我們求出線性基然後直接最大值。次大值就用最大值異或最小位上的基即可

這裡記一下線性基的兩個小性質。
若基的數量為n,則可以表達的數有2n
線性基求第k小,把k二進位制拆分然後把1的位上的基異或起來就可以了

Code


#include <stdio.h>
#include <string.h>
#define rep(i,st,ed) for (int i=st;i<=ed;++i) #define drp(i,st,ed) for (int i=st;i>=ed;--i) const int N=200005; struct Gay { int r[31]; void ins(int x) { drp(i,30,0) if ((x>>i)&1) { if (!r[i]) { r[i]=x; return ; } x^=r[i]; } } void get_max() { int res=0; drp(
i,30,0) if ((res^r[i])>res) res^=r[i]; printf("%d ", res); rep(i,0,30) if ((res^r[i])<res) { printf("%d\n", res^r[i]); return ; } } } G; int read() { int x=0,v=1; char ch=getchar(); for (;ch<'0'||ch>'9';v=(ch=='-')?(-1):(v),ch=getchar()); for (;ch<='9'&&ch>='0';x=
x*10+ch-'0',ch=getchar()); return x*v; } int main(void) { int n=read(); rep(i,1,n) { int x=read(); G.ins(x); } G.get_max(); return 0; }