线性基

大佬博客

#include<bits/stdc++.h>
#define re return
#define ll long long
#define dec(i,l,r) for(ll i=l;i>=r;--i)
#define inc(i,l,r) for(ll i=l;i<=r;++i) 
using namespace std;
template<typename T>inline void rd(T&x)
{
    char c;bool f=0;
    while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
    x=c^48;
    while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
    if(f)x=-x;
}

ll n,p[70];

inline void insert(ll x)
{
    //不断插入一个数
    //如果他不能被当前数表示出来
    //就在不能表示的最低位插入 
    dec(i,62,0)
    //为了不爆long long最好在63以内 
    if((x>>((ll)i)))
    {
        if(!p[i])
        {
            p[i]=x;
            re ;
        }
        x^=p[i];
    }
    
    re;
}
int main()
{
    //这题开long long 最好所有变量包括循环都开 
    freopen("in.txt","r",stdin);
    rd(n);
    ll x;
    inc(i,1,n)
    {
        rd(x);
        insert(x);
    }
    
    ll sum=0;
    dec(i,62,0)
    if((sum^p[i])>sum)
    //从高到底插入 
    sum^=p[i];
    printf("%lld",sum);
    re 0;
} 

 查询第K小

#include<bits/stdc++.h>
#define re return
#define dec(i,l,r) for(ll i=l;i>=r;--i)
#define inc(i,l,r) for(ll i=l;i<=r;++i)
using namespace std;
template<typename T>inline void rd(T&x)
{
    char c;bool f=0;
    while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
    x=c^48;
    while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
    if(f)x=-x;
}

#define ll long long
ll n,Q,p[64],cnt,ans[65];

inline void insert(ll x)
{
    dec(i,63,0)
    if(x>>i)
    {
        if(!p[i])
        {
            p[i]=x;
            re ;
        }
        x^=p[i];
    }
    re ;
}

inline void Gauss()
{
    dec(i,63,0)
    if(p[i])
    {
        inc(j,i+1,63)
        if((p[j]>>(j-i))&1)
        p[j]^=p[i];
    }
    //高斯消元???
    //将基向量弄成互不影响的那种
    
    memset(ans,0,sizeof ans);
    inc(i,0,63)
    if(p[i])
        ans[cnt++]=p[i];

}

int main()
{
    ll x,T,n,tot;
    rd(T);
    while(T--)
    {
        printf("Case #%d:
",++tot);
        rd(n);
        cnt=0;
        memset(p,0,sizeof p);
        
        inc(i,1,n)
        {
            rd(x);
            insert(x);
        }
        
        Gauss();
        
        rd(Q);
        inc(i,1,Q)
        {
            rd(x);
            if(n!=cnt)x--;//异或后可能会有0的存在 
            if(x>=(1ll<<cnt))
            printf("-1
");
            else 
            {
                ll sum=0;
                inc(j,0,cnt-1)
                if((x>>j)&1)
                sum^=ans[j];
                printf("%lld
",sum);
                
            }
        }
    }
    re 0;
}
原文地址:https://www.cnblogs.com/lsyyy/p/11551282.html