1. 程式人生 > >BZOJ_4269_再見Xor_線性基

BZOJ_4269_再見Xor_線性基

AI 包含 spa continue clas space while 100% 因此

BZOJ_4269_再見Xor_線性基

Description

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

Input

第一行一個正整數N。 接下來一行N個非負整數。

Output

一行,包含兩個數,最大值和次大值。

Sample Input

3
3 5 6

Sample Output

6 5

HINT

100% : N <= 100000, 保證N個數不全是0,而且在int範圍內
高斯消元求線性基。 線性基有如下性質:   每一列最多只有一個一。 因此所有線性基異或起來一定是最大的,並且異或上最後一個一定是次大的。 同理我們可以求出第k大的。 代碼:
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <bitset>
using namespace std;
int n,a[100050],b[100],cnt,tot;
void Gauss() {
    int i,j;
    for(i=(1<<30);i;i>>=1) {
        tot++;
        int mx=tot;
        while(mx<=n&&!(a[mx]&i)) mx++;
        if(mx==n+1) {
            tot--; continue;
        }
        b[++cnt]=i;
        swap(a[tot],a[mx]);
        for(j=1;j<=n;j++) {
            if(tot!=j&&(a[j]&i)) a[j]^=a[tot];
        }
    }
}
int main() {
    scanf("%d",&n);
    int i;
    for(i=1;i<=n;i++) scanf("%d",&a[i]);
    Gauss();
    int ans=0;
    for(i=1;i<=tot;i++) ans^=a[i];
    printf("%d %d\n",ans,ans^a[tot]);
}

BZOJ_4269_再見Xor_線性基