线性基

线性基是啥?
       你可以理解为将一个序列处理完之后得到的产物,有如下性质:

  1. 原序列里面的任意一个数都可以由线性基里面的一些数异或得到。
  2. 线性基里面的任意一些数异或起来都不能得到0
  3. 线性基里面的数的个数唯一,并且在保持性质一的前提下,数的个数是最少的
struct Linear_Basis
{
    ll b[63],nb[63],tot;

    void init()
    {
        tot=0;
        memset(b,0,sizeof(b));
        memset(nb,0,sizeof(nb));
    }

    bool ins(ll x)
    {
        for(int i=62;i>=0;i--)
            if (x&(1LL<<i))
            {
                if (!b[i]) {b[i]=x;break;}
                x^=b[i];
            }
        return x>0;
    }

    ll Max(ll x)
    {
        ll res=x;
        for(int i=62;i>=0;i--)
            res=max(res,res^b[i]);
        return res;
    }

    ll Min(ll x)
    {
        ll res=x;
        for(int i=0;i<=62;i++)
            if (b[i]) res^=b[i];
        return res;
    }

    void rebuild()
    {
        for(int i=62;i>=0;i--)
            for(int j=i-1;j>=0;j--)
                if (b[i]&(1LL<<j)) b[i]^=b[j];
        for(int i=0;i<=62;i++)
            if (b[i]) nb[tot++]=b[i];
    }

    ll Kth_Max(ll k)
    {
        ll res=0;
        for(int i=62;i>=0;i--)
            if (k&(1LL<<i)) res^=nb[i];
        return res;
    }

} LB;

P3812 【模板】线性基

#include<bits/stdc++.h>
using namespace std;
#define ls rt<<1
#define rs (rt<<1)+1
#define ll long long
#define fuck(x) cout<<#x<<"     "<<x<<endl;
const int maxn=1e5+10;
int d[4][2]= {1,0,-1,0,0,1,0,-1};
ll b[63],nb[63],a[100],tot;//二进制位从0开始计,符号位不能动

void init()
{
    tot=0;
    memset(b,0,sizeof(b));
    memset(nb,0,sizeof(nb));
}

void myinsert(ll x)
{
    for(int i=62; i>=0; i--)
        if (x&(1LL<<i))
        {
            if (!b[i])
            {
                b[i]=x;
                break;
            }
            x^=b[i];
        }
}

ll mymax(ll x)
{
    ll res=x;
    for(int i=62; i>=0; i--)
        res=max(res,res^b[i]);
    return res;
}

ll mymin(ll x)
{
    ll res=x;
    for(int i=0; i<=62; i++)
        if (b[i])
            res^=b[i];
    return res;
}

void rebuild()//在求k大时先rebuild
{
    for(int i=62; i>=0; i--)
        for(int j=i-1; j>=0; j--)
            if (b[i]&(1LL<<j))
                b[i]^=b[j];
    for(int i=0; i<=62; i++)
        if (b[i])
            nb[tot++]=b[i];
}

ll kmax(ll k)
{
    ll res=0;
    for(int i=62; i>=0; i--)
        if (k&(1LL<<i))
            res^=nb[i];
    return res;
}

int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%lld",&(a[i])),myinsert(a[i]);
    printf("%lld\n",mymax(0));
    return 0;
}

参考博客

https://blog.csdn.net/qaq__qaq/article/details/53812883

https://blog.csdn.net/a_forever_dream/article/details/83654397

posted @ 2019-07-19 16:41  eason99  阅读(105)  评论(0编辑  收藏  举报