CF1100F Ivan and Burgers(离线可删除线性基)

CF1100F Ivan and Burgers
题意比较清晰
(远古时期写的题,现在才写题解)
就是区间线性基

先考虑离线,按照右端点排序
考虑线性基的过程,就是这一位有值就取上
那么计 p o s [ i ] pos[i] pos[i]表示第 i i i位有值的最大的 l l l( l < = r l<=r l<=r)
然后像正常的线性基一样插入值
如果 p o s [ i ] pos[i] pos[i]>=l就表示第 i i i位有值,可以取
然后干就完了

#include<bits/stdc++.h>
#define N 1000005
using namespace std;
struct Q{
	int l, r, id;
}q[N];
int cmp(Q x, Q y){
	return x.r < y.r;
}
int n, a[N], m, ha[N], p[N], ANS[N];
void xxj(int x, int id){
	for(int i = 20; i >= 0; i --){
		if(x & (1 << i)){
			if(!p[i]){
				p[i] = x;
				ha[i] = id;
				return;
			}
			if(ha[i] < id) swap(ha[i], id), swap(x, p[i]);
			x ^= p[i];
		}
	}
}
int query(int l){
	int ret = 0;
	for(int i = 20; i >= 0; i --){
		if((p[i] ^ ret) > ret && ha[i] >= l) ret ^= p[i];
	}
	return ret;
}
int main(){
	scanf("%d", &n);
	for(int i = 1; i <= n; i ++) scanf("%d", &a[i]);
	scanf("%d", &m);
	for(int i = 1; i <= m; i ++) scanf("%d%d", &q[i].l, &q[i].r), q[i].id = i;
	sort(q + 1, q + 1 + m, cmp);
	int pos = 0;
	for(int i = 1; i <= m; i ++){
		while(pos + 1 <= q[i].r){
			pos ++;
			xxj(a[pos], pos);
		}
		ANS[q[i].id] = query(q[i].l);
	}
	for(int i = 1; i <= m; i ++) printf("%d\n", ANS[i]);
	return 0;
}
posted @ 2020-10-16 21:48  lahlah  阅读(54)  评论(0编辑  收藏  举报