随笔 - 73  文章 - 0 评论 - 0 阅读 - 6680
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

线性基

线性基可以解决子集异或的问题.

用处:

  • 快速查询一堆数可以异或出来的最大/最小值
  • 快速查询一个数是否可以被一堆数异或出来
  • 快速查询一堆数可以异或出来的第k大值

每一个序列都有线性基,性质:

  • 原序列里面的任意一个数都可以由线性基里面的一些数异或得到.
  • 线性基的元素能相互异或得到原集合的元素的所有相互异或得到的值。
  • 线性基中每个元素的异或方案唯一,也就是说,线性基中不同的异或组合异或出的数都是不一样的。
  • 线性基中每个元素的二进制最高位互不相同。

得到一个序列的线性基:

插入操作:

ll p[100];
void insert(ll x)
{
	for(int i = 62; i >= 0; i--)
	{
		if(!(x >> (ll)i))
			continue;
		if(!p[i])
		{
			p[i] = x;
			break;
		}
		x ^= p[i];
	}
}

查询最大值:

for(int i = 62; i >= 0; i--)
	if((ans ^ p[i]) > ans)
		ans ^= p[i];

查询一个元素是否可以被异或出来:

从高到低,如果这一位为11就异或上这一位的线性基,把11消去,根据性质一,如果最后得到了00,那这个数就可以表示出来。

int ask(LL x) {
	for(int i=62;i>=0;i--) 
		if(x&(1LL<<i)) x^=p[i];
	return x==0;
}
posted on   naiji  阅读(38)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示