zoukankan      html  css  js  c++  java
  • 2019 牛客暑期多校 第一场 H XOR (线性基)

    题目:https://ac.nowcoder.com/acm/contest/881/H

    题意:求一个集合内所有子集异或和为0的长度之和

    思路:首先集合内异或和,这是线性基的一个明显标志,然后我们不管怎么样先求出一个基A,秩为r

    我们枚举基外的数,每个数的贡献是  2^(n-r-1) ,为什么呢,因为其余数我都可以选择选或不选,无论什么组合,我都可以在基内表示出来,那么就肯定异或为0

    我们再来枚举基A内的数,我枚举当前数的时候把其余元素再求一遍基,然后以上面相同的道理计算贡献,

    #include<bits/stdc++.h> 
    #define maxn 100005
    #define mod 1000000007
    using namespace std;
    
    typedef long long LL;
    
    int n, r, tot;
    bool vis[maxn];
    vector<LL> vec;
    LL a[maxn], b[105], other[105], tmp[105];
    
    LL qpow(LL x, int n) {
        LL res = 1;
        while(n) {
            if(n & 1) res = res * x % mod;
            x = x * x % mod;
            n >>= 1;
        }
        return res;
    }
    
    bool ins(LL x, LL base[]) {
        for(int i = 63; i >= 0; --i) {
            if(x & (1LL << i)) {
                if(base[i]) x ^= base[i];
                else {
                    base[i] = x;
                    return true;
                }
            }
        }
        return false;
    }
    
    int main() {
        while(~scanf("%d", &n)) {
            r = tot = 0;
            vec.clear();
            for(int i = 0; i <= 63; ++i) b[i] = other[i] = 0;
            for(int i = 1; i <= n; ++i) {
                scanf("%lld", &a[i]);
                vis[i] = 0;
                if(ins(a[i], b)) vis[i] = 1, ++r, vec.emplace_back(a[i]);
            }
            if(r == n) {
                printf("0
    ");
                continue;
            }
            LL ans = qpow(2, n - r - 1) * (n - r) % mod;;
            for(int i = 1; i <= n; ++i) {
                if(vis[i]) continue;
                ins(a[i], other);
            }
            for(int i = 0; i < vec.size(); ++i) {
                tot = 0;
                for(int j = 0; j <= 63; ++j) tmp[j] = 0;
                for(int j = 0; j < vec.size(); ++j) {
                    if(i == j) continue;
                    if(ins(vec[j], tmp)) ++tot;
                }
                for(int j = 0; j <= 63; ++j) {
                    if(other[j] && ins(other[j], tmp)) ++tot;
                }
                if(!ins(vec[i], tmp)) {
                    ans = (ans + qpow(2, n - tot - 1)) % mod;
                }
            }
            printf("%lld
    ", ans);
        }
        return 0;
    }
  • 相关阅读:
    vue-slot插槽
    js中filter函数
    js异步处理
    js变量提升
    js中的4种函数调用模式
    js方法
    Javascript中的闭包 O__O "…
    js实现瀑布流以及加载效果
    2D转换下的zoom和transform:scale的区别
    [转]JavaScript与元素间的抛物线轨迹运动
  • 原文地址:https://www.cnblogs.com/Lis-/p/11291470.html
Copyright © 2011-2022 走看看