前缀线性基——关于目前的理解以及一些样题

news2024/10/6 2:51:43

 怎么说呢?在前几天我总结了了有关线性基的一篇博客,线性基用来去求整个区间的异或最值问题

前缀线性基——用于统计一个区间内的异或最值问题

 那么我们如何去统计呢?那么就要去存储一个区间的异或空间线性基,因此我们的思路就是用base[ p ] [ i ] 表示第p版本(统计从下标1~p上元素的线性基)的第i为上存储的线性基是什么

用pos[ p ] [ i ]去表示第p版本上的第i位上的线性基其元素来自于哪个下标的数

那么我们如何去查询呢?

我们去看当前右区间这个版本的线性基的位置,如果当前第i位上的线性基如果小于L,那么就说明此处线性基不存在于这个区间中,不用算这个线性基

然后就是正常求最值了

直接看样例

例题

F. Ivan and Burgers

其实这题就是一道完完全全的前缀线性基板题, 就是说给你n个数,然后q个询问,然后每次给你一个边界L和R,然后问你这个区间里面的异或最大值是多少

我们之间用前缀线性基去解决就行,具体注释我添加在代码里面,不懂私信即可

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,q;
int x;
int base[500005][32];//表示从1~i的版本上的第j位线性基的值
int pos[500005][32];//表示从1~i的版本上的第j位线性基的位置
int l,r;

void add(int x,int id)
{
	for(int i=0;i<32;i++)
	{
		base[id][i]=base[id-1][i];//子承父
		pos[id][i]=pos[id-1][i];
	}
	int p=id;//记录当前的版本号方便操作
	for(int i=31;i>=0;i--)
	{
		if((x>>i)&1)
		{
			if(!base[id][i])//如果当前位线性基是空的,可以直接插入
			{
				base[id][i]=x;
				pos[id][i]=p;//记录当前位线性基的位置
				break;
			}
			else
			{
				if(pos[id][i]<p)//如果当前位的线性基不是空的,要更新当前线性基的值向右方拓展
				{
					swap(base[id][i],x);//交换线性基的值
					swap(pos[id][i],p);//位置也会相应发生改变
				}
				x^=base[id][i];
			}
		}
	}
}

int find(int l,int r)
{
	int ans=0;
	for(int i=31;i>=0;i--)
	{
		if(pos[r][i]<l)
		{
			continue;
		}
		ans=max(ans,ans^base[r][i]);
	}
	return ans;
}

signed main()
{
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>x;
		add(x,i);
	}
	cin>>q;
	for(int i=1;i<=q;i++)
	{
		cin>>l>>r;
		cout<<find(l,r)<<"\n";
	}
	return 0;
}

P3292 [SCOI2016] 幸运数字

 题解:其实也是一道前缀线性基的问题,只不过还需要用到LCA+线性基合并

我们可以将一条路径上的链拆分为两条链,假设lca是x和y点的最近公共祖先,那么我们就可以将这条路径拆分为x~lca链和y~lca链,然后,我们就先将x链的线性基插入到线性空间中,然后将y链的线性基合并到线性空间中即可解决问题

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,q;
int a[20005];
int u,v;
vector<int> e[20005];
int dep[20005];
int f[20005][16];
int base[20005][64];
int pos[20005][64];
int b[20005];
void add(int v,int fa)
{
    for(int i=0; i<=63; i++)
    {
        base[v][i]=base[fa][i];
        pos[v][i]=pos[fa][i];
    }
    int x=a[v];
    int p=v;
    for(int i=63; i>=0; i--)
    {
        if((x>>i)&1)
        {
            if(!base[v][i])
            {
                base[v][i]=x;
                pos[v][i]=p;
                break;
            }
            else
            {
                if(dep[pos[v][i]]<dep[p])
                {
                    swap(base[v][i],x);
                    swap(pos[v][i],p);
                }
                x^=base[v][i];
            }
        }
    }
}

void dfs(int v,int fa)
{
    dep[v]=dep[fa]+1;
    f[v][0]=fa;
    for(int i=1; i<16; i++)
    {
        f[v][i]=f[f[v][i-1]][i-1];
    }
    add(v,fa);
    for(int u:e[v])
    {
        if(u!=fa)
        {
            dfs(u,v);
        }
    }
}

int LCA(int u,int v)
{
    if(dep[u]<dep[v])
    {
        swap(u,v);
    }
    for(int i=15; i>=0; i--)
    {
        if(dep[f[u][i]]>=dep[v])
        {
            u=f[u][i];
        }
    }
    if(u==v)
        return u;
    for(int i=15; i>=0; i--)
    {
        if(f[u][i]!=f[v][i])
        {
            u=f[u][i];
            v=f[v][i];
        }
    }
    return f[u][0];
}

int find(int x,int y)
{
    int lca=LCA(x,y);
    for(int i=63; i>=0; i--)
    {
        if(dep[pos[x][i]]>=dep[lca])
        {
            b[i]=base[x][i];
        }
        else
        {
            b[i]=0;
        }
    }
    for(int i=63; i>=0; i--)
    {
        if(dep[pos[y][i]]>=dep[lca])
        {
            int z=base[y][i];
            for(int j=i; j>=0; j--)
            {
                if((z>>j)&1)
                {
                    if(!b[j])
                    {
                        b[j]=z;
                        break;
                    }
                    else
                    {
                        z^=b[j];
                    }
                }
            }
        }
    }
    int ans=0;
    for(int i=63; i>=0; i--)
    {
        ans=max(ans,ans^b[i]);
    }
    return ans;
}

signed main()
{
    cin>>n>>q;
    for(int i=1; i<=n; i++)
    {
        cin>>a[i];
    }
    for(int i=1; i<=n-1; i++)
    {
        cin>>u>>v;
        e[u].push_back(v);
        e[v].push_back(u);
    }
    dfs(1,0);
    for(int i=1; i<=q; i++)
    {
        cin>>u>>v;
        cout<<find(u,v)<<"\n";
    }
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2190996.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【python】追加写入excel

输出文件运行前&#xff08;有两张表&#xff0c;“表1”和“Sheet1”&#xff09;&#xff1a; 目录 一&#xff1a;写入单表&#xff08;删除所有旧工作表&#xff0c;写入新表&#xff09;二&#xff1a;写入多表&#xff08;删除所有旧工作表&#xff0c;写入新表&#x…

平衡二叉搜索树之 AVL 树的模拟实现【C++】

文章目录 AVL树的简单介绍全部的实现代码放在了文章末尾准备工作包含头文件类的成员变量 构造函数和拷贝构造swap和赋值运算符重载析构函数findinsert[重要]当parent的平衡因子为1/-1时&#xff0c;如何向上更新祖先节点的平衡因子呢&#xff1f;怎么旋转&#xff1f;左单旋右单…

Windows Ubuntu下搭建深度学习Pytorch训练框架与转换环境TensorRT

Windows Ubuntu下搭建深度学习Pytorch训练框架与转换环境TensorRT JetBrains2024&#xff08;IntelliJ IDEA、PhpStorm、RubyMine、Rider……&#xff09;安装包Anaconda Miniconda安装.condarc 文件配置镜像源查看conda的配置和源(channel)自定义conda虚拟环境路径conda常用命…

Chromium 中JavaScript Screen API接口c++代码实现

Screen - Web API | MDN (mozilla.org) Screen Screen 接口表示一个屏幕窗口&#xff0c;往往指的是当前正在被渲染的 window 对象&#xff0c;可以使用 window.screen 获取它。 请注意&#xff1a;由浏览器决定提供屏幕对象&#xff0c;此对象一般通过当前浏览器窗口活动状…

《python语言程序设计》2018版第8章19题几何Rectangle2D类(下)-头疼的几何和数学

希望这个下集里能有完整的代码 一、containsPoint实现 先从网上找一下Statement expected, found Py:DEDENTTAB还是空格呢??小小总结如何拆分矩形的四个点呢.我们来小小的测试一下这个函数结果出在哪里呢???修改完成variable in function should be lowercase 函数变量应该…

No.2 笔记 | 网络安全攻防:PC、CS工具与移动应用分析

引言 在当今数字化时代,网络安全已成为每个人都应该关注的重要话题。本文将总结一次关于网络安全攻防技术的学习内容,涵盖PC端和移动端的恶意程序利用,以及强大的渗透测试工具Cobalt Strike的使用。通过学习这些内容,我们不仅能够了解攻击者的手法,更能提高自身的安全意识和防…

【牛顿迭代法求极小值】

牛顿迭代法求极小值 仅供参考 作业内容与要求 作业内容 作业要求 递交报告 代码 编程实现 计算偏导数 故上述非线性方程组的根可能为 f ( x , y ) f(x, y) f(x,y)的极值点&#xff0c;至于是极小值点还是极大值点或鞍点&#xff0c;就需要使用微积分中的黑塞矩阵来判断了。…

网络基础 【HTTPS】

&#x1f493;博主CSDN主页:麻辣韭菜&#x1f493;   ⏩专栏分类&#xff1a;Linux初窥门径⏪   &#x1f69a;代码仓库:Linux代码练习&#x1f69a; &#x1f4bb;操作环境&#xff1a; CentOS 7.6 华为云远程服务器 &#x1f339;关注我&#x1faf5;带你学习更多Linux知识…

Linux之实战命令26:timeout应用实例(六十)

简介&#xff1a; CSDN博客专家、《Android系统多媒体进阶实战》一书作者 新书发布&#xff1a;《Android系统多媒体进阶实战》&#x1f680; 优质专栏&#xff1a; Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a; 多媒体系统工程师系列【…

安卓手机密码忘了怎么办?(只做科普)

注意&#xff1a;只做科普&#xff0c;拒绝利用技术做一些非法事情 科普人&#xff1a;网络安全工程师~DL 科普平台&#xff1a;快手&#xff0c;CSDN&#xff0c;微信公众号&#xff0c;小红书&#xff0c;百度&#xff0c;360 本期文章耗时比较大&#xff0c;如果喜欢&…

数学题-分糖果-答案解析

PDF文档回复:20241005 1[题目描述] 幼儿园有7个小朋友&#xff0c;你是其中之一&#xff0c;有一天你发现无穷多颗糖&#xff0c;最少可以拿16个&#xff0c;最多可以拿23个&#xff0c;你打算拿一些分给小朋友们&#xff0c;分配原则是如果每人(包括你)都可以拿1块糖&#xf…

快速上手C语言【上】(非常详细!!!)

目录 1. 基本数据类型 2. 变量 2.1 定义格式 和 命名规范 2.2 格式化输入和输出&#xff08;scanf 和 printf&#xff09; ​编辑 2.3 作用域和生命周期 3. 常量 4. 字符串转义字符注释 5. 操作符 5.1 双目操作符 5.1.1 算数操作符 5.1.2 移位操作符 5.1.3 位操作符…

IDEA下“File is read-only”可能原因及“找不到或无法加载主类”问题的解决

1.File is read-only”可能原因 写代码时想要修改这个静态变量的值&#xff0c;把这个语句注释掉&#xff0c;发现在这个文件中File is read-only无法编辑修改&#xff0c;于是想去掉这个状态 网上查看的解释大多是在File栏目或File->File Properties下可以找到Make File W…

Git介绍--github/gitee/gitlab使用

一、Git的介绍 1.1、学习Git的原因&#xff1a;资源管理 1.2、SCM软件的介绍 软件配置管理(SCM)是指通过执行版本控制、变更控制的规程&#xff0c;以及使用合适的配置管理软件来保证所有配置项的完整性和可跟踪性。配置管理是对工作成果的一种有效保护。 二、版本控制软件 …

常见的基础系统

权限管理系统支付系统搜索系统报表系统API网关系统待定。。。 Java 优质开源系统设计项目 来源&#xff1a;Java 优质开源系统设计项目 | JavaGuide 备注&#xff1a;github和gitee上可以搜索到相关项目

企业必备:搭建大模型应用平台实操教程

最近AI智能体很火&#xff0c;AI智能体平台化产品肯定属于大公司的。但在一些场景下&#xff0c;尤其是对业务数据要求很高的公司&#xff0c;那就只能用私有大模型。不一定完全是为了对外提供服务&#xff0c;对内改造工作流也是需要的。所以 我感觉未来大部分企业都会搞一个…

软考系统分析师知识点二:经济管理

前言 今年报考了11月份的软考高级&#xff1a;系统分析师。 考试时间为&#xff1a;11月9日。 倒计时&#xff1a;35天。 目标&#xff1a;优先应试&#xff0c;其次学习&#xff0c;再次实践。 复习计划第一阶段&#xff1a;扫平基础知识点&#xff0c;仅抽取有用信息&am…

数字乡村综合解决方案

1. 项目背景与战略 《中共中央、国务院关于实施乡村振兴战略的意见》强调实施数字乡村战略的重要性&#xff0c;旨在通过信息技术和产品服务推动农业农村现代化&#xff0c;实现城乡数字鸿沟的弥合。 2. 数字乡村发展纲要 《数字乡村发展战略纲要》明确了全面建成数字乡村的…

颍川陈氏始祖陈寔逆势崛起的原由(二)有贵人相助

园子说颍川 陈寔崛起之初&#xff0c;有两个贵人发挥了关键作用。 第一个就是许县县令邓邵&#xff0c;如果不是他推荐青年陈寔去太学读书&#xff0c;陈寔可能一辈子就要待在许县县衙当小吏了。关于他的记载不详&#xff0c;光这一件事就让他名垂青史&#xff0c;帮助一个穷…

为Floorp浏览器添加搜索引擎及搜索栏相关设置. 2024-10-05

Floorp浏览器开源项目地址: https://github.com/floorp-Projects/floorp/ 1.第一步 为Floorp浏览器添加搜索栏 (1.工具栏空白处 次键选择 定制工具栏 (2. 把 搜索框 拖动至工具栏 2.添加搜索引擎 以添加 搜狗搜索 为例 (1.访问 搜索引擎网址 搜狗搜索引擎 - 上网从搜狗开始 (2…