被卡常求助
查看原帖
被卡常求助
142114
Fasterfaster楼主2023/2/1 17:19

RT, node.p[i]是当前节点线性基, node.n2g[i]代表node.p[i]由奇数/偶数个元素合成,其余应该不难懂,本地运行随机测试数据约6s

#include<bits/stdc++.h>
using namespace std;

int read () {
    int a = 1, x = 0;
    char c = getchar();
    while (!isdigit(c)) a = (c == '-' ? -a : a), c = getchar();
    while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
    return a * x;
}
void write (int x) {
    if (x < 0) putchar('-'), x = -x;
    if (x > 9) write(x / 10);
    putchar(x % 10 + 48);
}

struct node {
	int p[30], lb, rb, lz;
    bool n2g[30];
	node *ls, *rs;
	node () {
		ls = rs = NULL;
		lb = rb = lz = 0;
		memset(p, 0, sizeof(p));
		memset(n2g, 0, sizeof(n2g));
	}
};
void insert (int *p, bool *n2g, bool bn2g, int x) {
	for (register int i = 29;i >= 0;i--) {
		if (x & (1 << i)) {
			if (!p[i]) {
				p[i] = x;
				n2g[i] = bn2g;
				break;
			}
            x ^= p[i];
            bn2g ^= n2g[i];
		}
	}
}
void insert (int *p, int x) {
	for (register int i = 29;i >= 0;i--) {
		if (x & (1 << i)) {
			if (p[i]) x ^= p[i];
			else {
				p[i] = x;
				break;
			}
		}
	}
}
node *build(int lb, int rb, int *a) {
	node *newnode = new node;
	newnode -> lb = lb;
	newnode -> rb = rb;
	if (lb != rb) {
		int mid = (lb + rb) >> 1;
		newnode -> ls = build(lb, mid, a);
		newnode -> rs = build(mid+1, rb, a);
		for (register int i = 0;i < 30;i++) newnode -> p[i] = newnode -> ls -> p[i], newnode -> n2g[i] = newnode -> ls -> n2g[i];
		for (register int i = 0;i < 30;i++) insert(newnode -> p, newnode -> n2g, newnode -> rs -> n2g[i], newnode -> rs -> p[i]);
	}
	else insert(newnode -> p, newnode -> n2g, 1, a[lb]);
	return newnode;
}
int newp[30], p[30];
bool n2g[30];
void apply (node *cur, int v) {
	for (register int i = 0;i < 30;i++) {
        newp[i] = (cur -> p[i]) ^ (cur -> n2g[i] ? v : 0);
        n2g[i] = cur -> n2g [i];
        cur -> n2g[i] = cur -> p[i] = 0;
    }
	for (register int i = 0;i < 30;i++) insert (cur -> p, cur -> n2g, n2g[i], newp[i]);
}
void pushdown (node *cur) {
	if (cur -> lz) {
		cur -> ls -> lz ^= cur -> lz;
		apply (cur -> ls, cur -> lz);
		cur -> rs -> lz ^= cur -> lz;
		apply (cur -> rs, cur -> lz);
	    cur -> lz = 0;
	}
}
void modify (node *cur, int lb, int rb, int x) {
	if (cur -> lb == lb && cur -> rb == rb) {
		cur -> lz ^= x;
		apply (cur, x);
	}
	else {
		pushdown (cur);
		int mid = (cur -> lb + cur -> rb) >> 1;
		if (lb <= mid) modify (cur -> ls, lb, min(rb, mid), x);
		if (rb > mid) modify (cur -> rs, max(mid+1, lb), rb, x);
		for (register int i = 0;i < 30;i++) cur -> p[i] = cur -> ls -> p[i], cur -> n2g[i] = cur -> ls -> n2g[i];
		for (register int i = 0;i < 30;i++) insert(cur -> p, cur -> n2g, cur -> rs -> n2g[i], cur -> rs -> p[i]);
	}
}
void query (int *ans, node *cur, int lb, int rb) {
	if (cur -> lb == lb && cur -> rb == rb) {
		for (register int i = 0;i < 30;i++) insert(ans, cur -> p[i]);
	}
	else {
		pushdown(cur);
		int mid = (cur -> lb + cur -> rb) >> 1;
		if (lb <= mid) query(ans, cur -> ls, lb, min(rb, mid));
		if (rb > mid) query(ans, cur -> rs, max(mid+1, lb), rb);
	}
}
node *root;
int n, m, a[50005];
int main () {
	n = read(), m = read();
	for (register int i = 1;i <= n;i++) {
		a[i] = read();
	}
	root = build(1, n, a);
	int opt, l, r, x;
	while (m--) {
		opt = read(), l = read(), r = read(), x = read();
		if (opt == 1) modify(root, l, r, x);
		else {
			int ans = 0;
			for (register int i = 0;i < 30;i++) p[i] = 0;
			query(p, root, l, r);
			for (register int i = 29;i >= 0;i--) {
				if ((ans ^ p[i] ^ x) > (ans ^ x)) ans ^= p[i];
			}
			write (ans ^ x);
            putchar('\n');
		}
	}
}
2023/2/1 17:19
加载中...