2019頭の牛オフ以上の学校最初のベースリニアテンプレートフィールドH XOR

H XOR

問題の意味

排他的OR 0での全てのサブセットを満たすために求めている数字のセット、および長さを考えると、

分析

nは1E5である、それはこのグループ、我々は見つける可能なサブセットの列挙は、通常、各番号の貢献度に変換され、設定されたXORの数と0のために私たちは、リニアグループを検討確かです対数線形基、Rのグループセットの長さは、我々が線形代数の知識を知ることができ、配列に数値をとり、線形ベースは排他的論理和の組成が0であることが唯一の方法を有しています。各グループの数が線形でないためにので、数は彼のサブセットから構成されてもよい\(2-NR。1} ^ {\)すべての数の寄与が構成するように、直鎖状の基ではない\((NR)* 2 {NR-1} ^ \) その後、線形キリの数についてどのようにそれを行うには?、残りのn-1の数に変換は数字を表し、私たちはどのようにこれはショーができ、再びベースを求めるNRの残りの部分をカウントすることができますどのように多くの方法この番号を、表現することができませんその数は、単に線形定理により線形グループのセットの同じ数が異なることができ、知っているが、彼らは同じランクですが、この数は、内部リニアベースで表現されるように、彼、少数のために私たちの残りの部分、又はランクr場合、発現させることができ、その後、番号が構成されている数N 1-R-サブセット寄与することができる\(2-NR 1は} ^ {\) そうでなければ、寄与は0であります

#include <cstdio>
#include <cmath>
#include <algorithm>
#include<vector>
#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
typedef  long long  UI;
const int maxn=1e5+9;
int vis[maxn];
UI a[maxn];
const int mod=1e9+7;
ll mul(ll a,ll b){
    return a%mod*b%mod;
}
ll fpow(ll a,ll b){
    ll ans=1;
    while(b){
        if(b&1)ans=mul(ans,a);
        b>>=1;
        a=mul(a,a);
    }
    return ans;
}
#define weishu 62
UI x[weishu+1];
struct LinearBasis{
    UI basis[weishu+1];//32位
    int num;
    int cnt;//极大无关组大小
    void clear(){ memset(basis,0,sizeof(basis)); num=0;cnt=0; }//清零
    void insert(UI x){ basis[num++]=x; }//单纯存数组,没有插入线性基
    bool d_insert(UI x){//直接插入线性基
        bool flag=0;
           for(int j=weishu;j>=0;j--)
            if ((x>>j)&1) {
                if (basis[j]==0) {
                    cnt++;
                    basis[j]=x;
                    return 1;
                }
                else {
                    x^=basis[j];
                }
        }
           return 0;
    }
    void build(){//用数组里面存的数生成线性基
        cnt=0;
        num--;
        for(int i=0;i<=num;i++) x[i]=basis[i];
        memset(basis,0,sizeof(basis));
       for(int i=0;i<=num;i++)  {
           for(int j=weishu;j>=0;j--)
            if ((x[i]>>j)&1) {
                if (basis[j]==0) {
                    cnt++;
                    basis[j]=x[i];
                    break;
                }
                else {
                    x[i]^=basis[j];
                }
            }
        }
        num=0;
    }
    int check(UI x){//判断一个数在不在线性基中
       for(int i=weishu;i>=0;i--)
        if ((x>>i)&1) {
            if (basis[i]==0) break;
            else x^=basis[i];
        }
        return (x==0);
    }
}bs,bs2;
vector<int>v;
int main(){
    int n;
    while(scanf("%d",&n)==1){
        v.clear();
        bs.clear(),bs2.clear();
        for(int i=1;i<=n;i++){
            vis[i]=0;
            scanf("%lld",&a[i]);
        }
        for(int i=1;i<=n;i++){
            if(bs.d_insert(a[i])){
                v.push_back(i);
                vis[i]=1;
            }
        }
        ll r=bs.cnt;
        ll ans=mul(n-bs.cnt,fpow(2,n-bs.cnt-1));
        for(int i=1;i<=n;i++){
            if(vis[i]==0){
                    bs2.d_insert(a[i]);
            }
        }
        for(int i=0;i<v.size();i++){
            bs=bs2;
            for(int j=0;j<v.size();j++){
                if(i!=j){
                    bs.d_insert(a[v[j]]);
                }
            }
            if(bs.cnt==r)ans+=fpow(2,n-1-r);
        }
        ans%=mod;
        printf("%lld\n",ans);
 
 
 
    }
    return 0;
}

おすすめ

転載: www.cnblogs.com/ttttttttrx/p/11432117.html