首页 > 其他分享 >线性基详解+例题

线性基详解+例题

时间:2024-01-27 19:55:36浏览次数:21  
标签:int long 异或 详解 MAXN ans 线性 例题

线性基

线性基是一个能够在每次时间复杂度\(O(\log_2d)\),d是数字的位数内处理异或最大最小的数据结构。

问题:请你维护一个数据结构,支持插入一个数,求这些数任意异或得到的结果是否可能为某一个数、最大值、最小值、第k小值。

做法:开一个数组a[MAXN],MAXN是数字最高位数。

a[i]表示当前线性基内任意异或出来的数字中,最高位为i的任意一个数字。

#define MAXN 60
long long a[64];

插入x|判断x是否可以由线性基得到

高位到低位 枚举所有位数,如果x的第i位为0则不管,如果x的第i位为1:

1.如果a[i]不存在,更新线性基 a[i]=x,并退出。

2.如果a[i]存在,令x^=a[i]。

如果最后x变成了0,那么说明x可以由线性基异或得到。

void Insert(long long x)
{
    for(int i = MAXN; i >= 0; i--)
    {
        if(x & (1LL << i))
        {
            if(!a[i]){a[i] = x;return;}
            x ^= a[i];
        }
    }
}

查询最大值

从高位到低位扫描线性基。如果异或之后答案变大,就把这一位异或到答案。

long long getmax()
{
    long long ans = 0;
    for(int i = MAXN; i >= 0; i--)
    {
        if((ans ^ a[i]) > ans)
            ans ^= a[i];
    }
    return ans;
}

查询最小值

从低位到高位扫描线性基。最低位上的线性基即为答案。

long long getmin()
{
    for(int i = 0; i <= MAXN; i++)
    {
        if(a[i] > 0)
            return a[i];
    }
}

模板

P3812 【模板】线性基

首先构建线性基

然后从高位往低位,只要能变成1就变成1

因为只要高位有1,就会比高位是0更优,就像二进制下的 1000...(n个0)>0111...(n个1)

第k小

首先我们要改造一下线性基。

我们把线性基改造成每一位相互独立,意思就是对于第i位,线性基上只有一个未知的第i位可能是1。

具体如何改造,就是从高位向低位扫描,对于第i位线性基a[i],对于j<i,如果a[i]的第j位是1,就让a[j]异或上a[i]。

查询的时候,将k进行二进制拆分,对于的1位,就异或对应的线性基。

最终得到的答案是第k小值。

int p[64],cnt;
void rebuild()
{
	for(int i = MAXN; i >= 0; i--)
    {
        for(int j = i - 1; j >= 0; j--)
            if(a[i] & (1LL << j))
                a[i] ^= a[j];
    }
    for(int i = 0; i <= MAXN; i++)
    {
        if(a[i])
            p[cnt++]=d[i];
    }
}

long long query(long long k)
{
    long long ans=0;
    rebuild();
    if(k >= (1LL << cnt))
    	return -1;
    for(int i = 0; i <= MAXN; ++i)
    {
        if(k & (1LL << i))
            ans ^= p[i];
    }
    return ans;
}

练习题目

题单

标签:int,long,异或,详解,MAXN,ans,线性,例题
From: https://www.cnblogs.com/wljss/p/17991847

相关文章

  • synchronized详解
    synchronized?是Java中的关键字,是一种同步锁。主要应用于多线程环境下保证线程的安全性。四种用法修饰一个代码块         被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象;synchronized(this)classSyncTh......
  • 【C#】快捷键详解
    注释:Ctrl+K,Ctrl+C取消注释:Ctrl+K,Ctrl+U添加#region:Ctrl+K,Ctrl+S格式化对齐:Ctrl+K,Ctrl+D生成getset:Ctrl+R,Ctrl+E转换小写:CTRL+U转换大写:CTRL+SHIFT+U启动调试:F5停止调试:Shift+F5单步执行:F11或F10跳出函数:Shift+F11查看变量值:鼠标悬停变量上代码格式化:Ct......
  • 注解@CrossOrigin详解
    转载自:https://blog.csdn.net/MobiusStrip/article/details/84849418文章目录注解@CrossOrigin一、跨域(CORS)支持:二、使用方法:1、controller配置CORS1.1、controller方法的CORS配置1.2、为整个controller启用@CrossOrigin1.3、同时使用controller和方法级别的C......
  • C# 面向对象编程进阶:构造函数详解与访问修饰符应用
    C#构造函数构造函数是一种特殊的方法,用于初始化对象。构造函数的优势在于,在创建类的对象时调用它。它可以用于为字段设置初始值:示例获取您自己的C#服务器创建一个构造函数://创建一个Car类classCar{publicstringmodel;//创建一个字段//为Car类创建一个......
  • C# 面向对象编程进阶:构造函数详解与访问修饰符应用
    C#构造函数构造函数是一种特殊的方法,用于初始化对象。构造函数的优势在于,在创建类的对象时调用它。它可以用于为字段设置初始值:示例获取您自己的C#服务器创建一个构造函数://创建一个Car类classCar{publicstringmodel;//创建一个字段//为Car类创建一......
  • Bellman-ford 详解
    讲解  模板 第1题    bellman-ford练习查看测评数据信息给定一个n个点m条边的有向图,图中可能存在重边但不存在自环,边权可能为负数。请你求出从1号点到n号点最短距离,如果无法从1号点走到n号点,输出impossible。1≤n≤500,1≤m≤10000,任意边长的绝对值......
  • spfa 详解
    算法基础 模板题 第1题    spfa最短路练习查看测评数据信息给定一个n个点m条边的有向图,图中可能存在重边和自环,边权可能为负数。请你求出1号点到n号点的最短距离,如果无法从1号点走到n号点,则输出impossible。数据保证不存在负权回路。1≤n,m≤100000......
  • floyd 详解
    解析  模板  第1题    floyd练习查看测评数据信息给定一个n个点m条边的有向图,图中可能存在重边和自环,边权可能为负数。再给定k个询问,每个询问包含两个整数x和y,表示查询从点x到点y的最短距离,如果路径不存在,则输出impossible。数据保证图中不存在......
  • 详解SpringCloud之远程方法调用神器Fegin
    第1章:引言咱们作为Java程序员,在微服务领域里,SpringCloud可谓是个耳熟能详的大名。它提供了一套完整的微服务解决方案,其中就包括了服务间的通信。在这个微服务中,有一个成员特别引人注意,它就是Feign。那Feign到底是什么呢?简单来说,Feign是一个声明式的Web服务客户端,它让编写Web服......
  • 【板子】线性基
    //lgp3812#include<bits/stdc++.h>usingnamespacestd;#definellunsignedlonglonglld[100];intn;voidInsert(llx){ for(inti=62;i>=1;i--) { if(!(x>>(i-1)))continue; if(!d[i]) { d[i]=x; return; } else { ......