2019牛客第一場h xor

應用了線性基的性質。

一個基可以表示向量空間裏任意一個數。

所以任意求一組基,計算每一個基之外的數的貢獻,就是這個數必選,其他數可選可不選

基之內的數,如果這個基不可被替代,那麼貢獻爲0,否則貢獻與基之外的數一樣。

​
#include <bits/stdc++.h>

using namespace std;
#define N 300005
#define pii pair<int,int>
#define go(i,a,b) for(int i=(a);i<=(b);i++)
#define dep(i,a,b) for(int i=(a);i>=(b);i--)
#define pb push_back
#define mid (l+r)/2
#define ls i*2+1
#define rs i*2+2
#define lson l,mid,ls
#define rson mid+1,r,rs
#define root 1,n+1,0
#define inf 0x3f3f3f3f
#define ll long long
#define M 63
#define mod 1000000007
ll data[N],b[70],c[70];

int f[N],pos[N],r,n;
inline ll cal(ll b[],ll x){
    dep(j,M,0)if(x>>j&1){
        if(!b[j])return b[j]=x;
        x^=b[j];
    }
    return 0;
}
ll qpow(ll a,ll b,ll res=1){for(;b>0;b/=2)res=res*((b&1)?a:1)%mod,a=a*a%mod;return res;}
int main()
{
    while(scanf("%d",&n)!=EOF){
        memset(b,0,sizeof b);r=0;
        
        go(i,1,n){
            scanf("%lld",&data[i]);
            f[i]=0; if(cal(b,data[i]))pos[++r]=i,f[i]=1 ;
        }
        
        ll ans=1ll*(n-r)*qpow(2,n-r-1)%mod;
        
        memset(b,0,sizeof b);
        go(i,1,n)if(!f[i])cal(b,data[i]);
        
        go(i,1,r){
            memcpy(c,b,sizeof b);
            go(j,1,r)if(i!=j)cal(c,data[pos[j]]);
            if(!cal(c,data[pos[i]])) ans=(ans+qpow(2,n-r-1))%mod;
        }
        
        printf("%lld\n",ans);
    }
}

​

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章