ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

线性基

2022-09-03 20:04:24  阅读:138  来源: 互联网

标签:基中 int 插入 异或 ans 线性


线性基,可以拿来搞异或一类的东西。它可以表示出原数组互相异或能异或出的所有值。

一些性质:

  1. 线性基的元素能相互异或得到原集合的元素的所有相互异或得到的值。
  2. 线性基是满足性质 1 的最小的集合。
  3. 线性基没有异或和为 0 的子集。
  4. 线性基中每个元素的异或方案唯一,也就是说,线性基中不同的异或组合异或出的数都是不一样的。
  5. 线性基中每个元素的二进制最高位互不相同。

构造:我不太懂。

void ins(int x){//将线性基中插入数 
	for(int i=63;i>=0;i--){
		if(!(x>>i))continue;
		if(!p[i]){//如果当前位有值且线性基当前位为0则改 
			p[i]=x;break;
		}
		x^=p[i];//反之异或当前值 
	}
}
bool query(int x){//查询一个数能否被线性基中数表出 
	for(int i=63;i>=0;i--){
		if((x>>i)&1)x^=p[i];//当前位有就异或一下 
	}
	if(x==0)return false;
	return true;
}

大概原理是线性基的当前位的最高位就是这一位(举个例子,p[60]的最高位是1<<60)。然后贪心就可以搞出来。

判断一组数能异或出的最大值也差不多的贪心就行。

int ans=0;
for(int i=63;i>=0;i--)ans=max(ans,ans^p[i]);

最小值同理,但是注意特判0,直接看有没有元素不能插入线性基就行了。

还有一个结论:设线性基大小为\(size\),原数组大小为\(n\),那么显然有\(2^{size}\)种不同的异或结果。而原数组有\(2^n\)种有重复的结果,每个结果重复\(2^{n-size}\)次(也就是平均分布)。

然后是一些科技:

  1. 前缀线性基

题意:一个序列,两种操作:区间选数异或最大值,序列末尾加一个数。强制在线。

前缀线性基,顾名思义,我们对每个前缀都建一个线性基,这样我们就只需要统计一个询问\([l,r]\)中\(l\)之后的部分对\([1,r]\)的贡献。

然后显然,如果插入两个数的效果相同,这个数的位置越靠后越好。所以我们记录一下线性基中的每个数的位置,如果能更改成位置更优的就更改一下。怎么搞?我们线性基插入的时候,如果一个位置有值且位置更优,就把要插入的数和线性基内的数换一下。代码实现如下:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
struct node{
	int p[32],pos[32];//值和位置 
	void ins(int x,int val){//x位置 val值 
		for(int i=31;i>=0;i--){
			if((val>>i)&1){
				if(!p[i]){
					p[i]=val;pos[i]=x;return;//没有就正常插入 
				}
				else if(pos[i]<x){
					swap(pos[i],x);swap(p[i],val);//有的话就更改一下 
				}
				val^=p[i];//正常流程 
			}
		}
	}
	int query(int l){
		int ans=0;
		for(int i=31;i>=0;i--){
			if(p[i]&&pos[i]>=l)ans=max(ans,ans^p[i]);//只有位置在l后面才更新 
		}
		return ans;
	}
}a[500010];
void update(int x){
	n++;a[n]=a[n-1];a[n].ins(n,x);
}
int find(int l,int r){
	return a[r].query(l);
}
  1. 带修线性基

题意:维护一堆数的线性基,要求插入、删除、查询异或最大值。强制在线。

首先如果不强制在线显然可以线段树分治乱搞。

我们可以维护线性基内所有的原数,插入就正常插入,删除开始分类讨论。(咕)

标签:基中,int,插入,异或,ans,线性
来源: https://www.cnblogs.com/gtm1514/p/16653401.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有