zoukankan      html  css  js  c++  java
  • 线性基

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

    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
    ",mymax(0));
        return 0;
    }
    

    参考博客

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

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

  • 相关阅读:
    mysql install steps
    d3js
    js布局库
    mac 学习笔记
    js图形库
    zeromq 笔记
    C语言程序员必读的5本书
    Java基础
    JS中的toString方法
    给你六种面额1 5 10 20 50 100元的纸币假设每种币值的数量足够多
  • 原文地址:https://www.cnblogs.com/eason9906/p/11754743.html
Copyright © 2011-2022 走看看