• 线性基学习笔记


    1.可以用于处理与异或有关的问题(异或最大值,一堆数中有无子集异或等于0,某数在一堆数异或中的排名)

    2.插入操作

    x=read();
    for(int j=60;j>=0;j--)
    {
        //cout<<(int)((int)1<<j)<<"
    ";
        if((int)((int)1<<j)&x)
        {
            if(p[j]==0)
            {
                p[j]=x;
                break;
            }
            else
                x^=p[j];
        }
    }

    3.性质

    (1)、线性基内任何子集的异或和不为0。

    (2)、线性基外的所有数必能由线性基内一些数异或得到。

    证明:

    (1)、如果插入数x后异或和为0,则x^p1^p2^……^pt=0。则x在插入时,异或p1,p2……后即为0,就不会插入x。

    (2)线性基外的数没有被插入,则肯定在中途被异或成0了,则他可以被线性基中一些数异或得到。

    4.查询异或最大值:

    直接在线性基中贪心,如果异或p[i]变得更大,就异或p[i]。

    首先由性质(2),原序列所有数都能被线性基内的数异或得到。那么最大值一定可以通过线性基中数异或得到。

    pi即表示可以异或一个二进制最高位为i的数。

    如果现在ans这一位为0,那肯定异或p[i]后变得更大,如果这一位是1,那异或p[i]这一位变成0了,随便咋个异或后头的数都莫得办法变大了,那就不异或。

    代码如下:

    int ans=0;
    for(int i=52;i>=0;i--)
    {
        ans=max(ans,ans^p[i]);
    }
    View Code

    5.

    查询排名第k小的数。

    首先如果有异或等于0的,先把k--,因为线性基里头莫得0。然后先把p数组 ( n^{2} )预处理一哈,如果p[i]&(1<<j) p[i]^=p[j] (j=i;j>=0;j--),就保证了靠这一位影响不到后头。然后就将k转成二进制,从0枚举到最高位,如果k第i为为1,就把答案异或上p中的从0到最高位上第i个元素即可。

    6.

    例题

    洛谷P4301

    P3265 (实数线性基)

    P3292

  • 相关阅读:
    golang中,new和make的区别
    k8s客户端库
    k8s 拉取私有镜像
    kubernetes-client / python
    k8s集群外go客户端示例
    K8s获取NodePort
    KUBERNETES中的服务发现机制与方式
    Rancher容器目录持久化
    rancher k8s 实现pod弹性伸缩
    在Terminal里,使用Shift+Insert来代替鼠标右键来进行粘贴操作
  • 原文地址:https://www.cnblogs.com/betablewaloot/p/12398143.html
Copyright © 2020-2023  润新知