Loading

xor 线性基

线性基求并

前缀线性基

考虑这样一个问题

对于一个数列,求 \([l,r]\) 中的数的异或最大值,强制在线。

如果 \([l,r]\) 是全集那么我们很容易使用线性基得到答案,考虑在线段树上维护线性基,但是这显然很蠢(复杂度会多一个 \(\log{n}\))。

考虑对每个 \(i\) 维护 \([1,i]\) 倒着插入的线性基,简单来说就是我们想要尽可能考虑 \(i\) 的数作为基。这并不需要真的倒着插入,只需在从前往后加入每个 \(i\) 的时候贪心判断即可。

具体的流程

  • 复制 \(i-1\) 的线性基

  • \(a[i]\) 插入

  • 插入时如果该位置已经有值,替换成 \(a[i]\)

struct Linear_Base{
	int a[31][2];
	void insert(int x, int pos) {
		for (int i = 30; i >= 0; i--) {
			if (x & (1 << i)) {
				if (!a[i][0]) {
					a[i][0] = x;
					a[i][1] = pos;
					break;
				} else {
					if (a[i][1] < pos) swap(a[i][0], x), swap(a[i][1], pos);
					x ^= a[i][0];
				}
			}
		}
	}
}xxj[maxn];

考虑查询,如果对于某一位最近的都比 \(l\) 小,那么我们就不能使用这一位。例查询最大值:

for (int i = 30; i >= 0; i--) {
	if (xxj[r].a[i][1] >= l) {
    	if ((ans ^ xxj[r].a[i][0]) > ans) {
        	ans ^= xxj[r].a[i][0];
        }
    }
}

习题

CF1100F

hdu6579

luogu3292(比什么点分治香多了)

hdu6845

线性基求交

带删线性基

posted @ 2022-06-05 20:50  Semsue  阅读(62)  评论(0编辑  收藏  举报
Title