zoukankan      html  css  js  c++  java
  • 线性基总结

    线性基三个性质:

    1. 原序列里面的任意一个数都可以由线性基里面的一些数异或得到。
    2. 线性基里面的任意一些数异或起来都不能得到0
    3. 线性基里面的数的个数唯一,并且在保持性质一的前提下,数的个数是最少的

    构造:arr数组为线性基数组,x为要插入的元素。

    void add(ll arr[],ll x) {
        for (int i = 63; i >= 0; i--) {
            if (x & (1ll<<i)) {
                if (arr[i]) x^=arr[i];
                else {
                    arr[i] = x;
                }
            }
        }
    }

      arr数组中存的元素arr[i]为二进制最高位1在第i+1位,如果这个位置已经有值了的话就对异或之后的值进行判断。

    可用于求一组数异或后的最大值:

    ll work()
    {
        ll ans=0;
        for(int i=63;i>=0;i--)
        if((ans^d[i])>ans) ans^=arr[i];
        return ans;
     }  

    也可用于求一组数异或后的最小值:

    ll work() {
        for (int i = 0; i <= n; i++) {
            if (arr[i]) return arr[i];
        }
    }

    求第k小:

    void work()//处理线性基
    {
        for(int i=1;i<=60;i++)
        for(int j=1;j<=i;j++)
        if(d[i]&(1<<(j-1)))d[i]^=d[j-1];
    }
    ll k_th(ll k)
    {
        if(k==1&&tot<n)return 0;//特判一下,假如k=1,并且原来的序列可以异或出0,就要返回0,tot表示线性基中的元素个数,n表示序列长度
        if(tot<n)k--;//类似上面,去掉0的情况,因为线性基中只能异或出不为0的解
        work();
        ll ans=0;
        for(int i=0;i<=60;i++)
        if(d[i]!=0)
        {
            if(k%2==1)ans^=d[i];
            k/=2;
        }
    }

    题目明天再写~

    模板题
    更多好题(难度非递增):
    BJWC 2011 元素   |  题解
    SCOI 2016 幸运数字  | 题解
    TJOI 2008 彩灯 

      参考:https://blog.csdn.net/a_forever_dream/article/details/83654397

  • 相关阅读:
    SQLSERVER Tempdb的作用及优化
    sqlserver分区表索引
    Install the mongdb
    mysql常用参数监控
    Mysql由浅入深
    nginx配置文件优化
    ping主机不通邮件报警
    top结果解释
    了解MQ
    kafka安装部署
  • 原文地址:https://www.cnblogs.com/l999q/p/11279571.html
Copyright © 2011-2022 走看看