zoukankan      html  css  js  c++  java
  • hdu3949

    线性基?

    线性基在我的理解下是一种向量基底,就是说每个数a[i],都能通过线性基组合出来。又因为线性基只有01,所以系数只有01

    这道题感觉就是确定每一个二进制位能不能通过xor组合出来,然后因为二进制可以通过贪心确定大小,因为选择最高位肯定是最大的,所以我们可以拆分k来确定每一位选还是不选。

    消元之后就能确定每个二进制位是否能选出来,因为高斯消元完了消出一组解,就肯定能通过选或不选某个数组合出来,肯定不会矛盾,比如说两个位是1,他们的组合矛盾了,这是不可能的,因为高斯消元求出了一组方程的解,解肯定满足任意一条方程。

    now的意思是能够通过now个元素组合出所有的数,这样的意思也就是有2^now-1个元素,其他的数都是重复。

    又理解了一下,就是把每个数消成只有一个1或0个1,0个1选不选无所谓,1个1有选或不选。所以就是选或不选变成了两个数,也就是我们有多少个消完后的a[i]不是0,那么我们就有2^个数-1个不重复的数(0不能出现) 这个东西和向量挺像的。

    上面是错的。。。不是最多有一个1,可以有很多个1,只有两个数3和4就不是只有一个1了。基底可以表示集合中所有的数。。。每个基底都是由几个数合成的,如果我们想用几个基底合成新的数的时候,如果我们缺少基底的元素,那么我们就加上,如果需要用以前用过的数,那么直接消掉,因为异或和自己异或可以消掉。这样总能组成一个新的数。线性基就是帮助我们找了一个最简的集合,里面的元素选或不选就能构造出新的数,这也就是线性基的意义所在,对于线性基的元素只用考虑选或不选。线性基的用处似乎还有很多,最重要的就是可以选择异或第k大的异或和,能很快地查询一个异或和的信息。

    还有一点不明白...

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N = 10010;
    int n, m, now;
    ll a[N], bin[70];
    void gauss()
    {
        now = 1;
        for(int i = 61; i >= 0; --i)
        {
            int j = now;
            while(j <= n && !(a[j] & bin[i])) ++j;
            if(j > n) continue; //这位没有,不能弄出来0 
            swap(a[now], a[j]);
            for(int j = 1; j <= n; ++j) if(j != now && a[j] & bin[i]) a[j] ^= a[now];
            ++now; //下一位 
        }
        --now; //可以弄出来2^now-1个数 
    }
    ll query(ll k)
    {
        ll ret = 0;
        if(now != n) --k;
        if(k >= bin[now]) return -1;
        for(int i = 1; i <= now; ++i) if(k & bin[now - i]) ret ^= a[i];
        return ret;
    }
    int main()
    {
        bin[0] = 1; for(int i = 1; i <= 61 ; ++i) bin[i] = bin[i - 1] << 1;
        int T, cas = 0; scanf("%d", &T);
        while(T--)
        {
            printf("Case #%d:
    ", ++cas); 
            scanf("%d", &n);
            for(int i = 1; i <= n; ++i) scanf("%lld", &a[i]);
            gauss();
            scanf("%d", &m);
            while(m--)
            {
                ll k; scanf("%lld", &k);
                printf("%lld
    ", query(k));
            }
        }
        return 0;
    } 
    View Code
  • 相关阅读:
    LeetCode数学系列(3)——快速幂算法(50题)
    LeetCode树系列(3)——200题岛屿数量
    Arrays.sort()详解
    图表示学习系列(1)——GCN学习笔记:第一部分,详细讲解GCN
    LeetCode动态规划系列(3)——编辑距离问题求解
    深度学习系列(9)——node2vec算法中的alias采样介绍
    LeetCode数学系列(2)——解决约瑟夫问题
    Java数据结构系列(4)——队列常用方法
    LeetCode树系列(1)——广度搜索应用,图的BFS
    LeetCode树系列(2)——深度搜索运用:LeetCode695题详解
  • 原文地址:https://www.cnblogs.com/19992147orz/p/6835057.html
Copyright © 2011-2022 走看看