首页 > 其他 > 详细

【LOJ#6060】Set(线性基)

时间:2018-12-31 18:16:15      阅读:198      评论:0      收藏:0      [点我收藏+]

【LOJ#6060】Set(线性基)

题面

LOJ

题解

好题啊QwQ。
首先\(x1\oplus x2=s\)是定值。而\(s\)中假设某一位上是\(1\),则\(x1,x2\)上必定有一个是\(1\),另一个是\(0\),所以对答案没有影响。反过来,如果\(s\)上某一位为\(0\),则要么都是\(0\),要么都是\(1\)
所以我们在考虑构造线性基的时候,优先考虑\(0\)的位,再考虑\(1\)的位。
那么现在只需要令\(x2\)在原本在\(s\)\(0\)的位置上取到尽可能多的\(1\)的情况下最大,这样子异或一下就是\(x1\)了。(好乱啊)

#include<iostream>
#include<cstdio>
using namespace std;
#define ll long long
#define MAX 100100
inline ll read()
{
    ll x=0;bool t=false;char ch=getchar();
    while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    if(ch=='-')t=true,ch=getchar();
    while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    return t?-x:x;
}
int n;ll a[MAX],s,p[70],s1,s2;
int b[70],tot;
void insert(ll x)
{
    for(int i=1;i<=tot;++i)
        if(x&(1ll<<b[i]))
        {
            if(!p[i]){p[i]=x;break;}
            else x^=p[i];
        }
}
int main()
{
    n=read();
    for(int i=1;i<=n;++i)a[i]=read(),s^=a[i];
    for(int i=62;~i;--i)if(!(s&(1ll<<i)))b[++tot]=i;
    for(int i=62;~i;--i)if(s&(1ll<<i))b[++tot]=i;
    for(int i=1;i<=n;++i)insert(a[i]);
    for(int i=1;i<=tot;++i)if(!(s2&(1ll<<b[i])))s2^=p[i];
    printf("%lld\n",s^s2);
    return 0;
}

【LOJ#6060】Set(线性基)

原文:https://www.cnblogs.com/cjyyb/p/10202339.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!