【BZOJ4269】再见Xor

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]);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值