首页 > 解决方案 > XOR 包含少于两个集合位的子集数

问题描述

我有一个数字数组 A(大小 <= 10^5)(<= 10^8),我需要回答一些查询(50000),对于 L,R,范围 [L, R],子集的 XOR 是具有 0 或 1 位集合的数字(2 的幂)。此外,数组中的点修改是在查询之间进行的,因此不能真正进行一些离线处理或使用平方根分解等技术。

我有一种方法,我使用 DP 计算给定范围,类似于以下内容: https ://www.geeksforgeeks.org/count-number-of-subsets-having-a-particular-xor-value/

但这显然太慢了。这感觉像是一个经典的线段树问题,但似乎无法找到每个节点要存储哪些数据点,因此我可以使用左孩子和右孩子来计算给定范围的答案。

标签: algorithmsubsetdynamic-programmingxorsegment-tree

解决方案


是的,那个DP不够快。

足够快的是在 GF(2) 上应用一些线性代数,GF(2) 是具有两个元素的伽罗瓦域。每个数字都可以解释为一个位向量;加/减向量是异或;标量乘法并不真正相关。

每个段需要的数据是 (1) 段中有多少个数字 (2) 段中的数字生成的数字子空间的基础,该子空间最多包含 27 个数字,因为所有数字都小于2^27。如果它不为零,则单元素段的基础就是那个数字,否则就是空集。要找到两个基并集的跨度,请使用高斯消除并丢弃零向量。

给定区间的长度和它的基础,您可以使用秩零定理计算好的子集的数量。基本上,对于每个目标数,使用您的高斯消除例程来测试目标数是否属于子空间。如果是这样,则有 2^(区间长度减去基础大小)子集。如果不是,答案是零。


推荐阅读