题意;
给定 n n n 个数,再有 q q q 次询问,每次询问 [ l , r ] [l,~r] [l, r] 中的任意子集异或最大值。 ( n , q ≤ 5 × 1 0 5 , a i ≤ 1 0 6 ) (n,~q \leq 5×10^5,~a_i \leq 10^6) (n, q≤5×105, ai≤106)
链接:
https://codeforces.com/contest/1100/problem/F
解题思路:
任意子集异或最大值,用线性基解决。对于区间询问,维护多个版本的线性基,每个版本贪心地使用下标最大的对应的基。
参考代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define sz(a) ((int)a.size())
#define pb push_back
#define lson (rt << 1)
#define rson (rt << 1 | 1)
#define gmid (l + r >> 1)
const int maxn = 5e5 + 5;
const int inf = 0x3f3f3f3f;
const int mod = 10086;
int b[maxn][20], p[maxn][20];
int n, m;
void insert(int cur, int pos, int val){
for(int i = 0; i <= 19; ++i){
b[cur][i] = b[cur - 1][i];
p[cur][i] = p[cur - 1][i];
}
for(int i = 19; i >= 0; --i){
if((val >> i) & 1){
if(!b[cur][i]){
b[cur][i] = val;
p[cur][i] = pos;
return;
}
if(pos > p[cur][i]){
swap(val, b[cur][i]);
swap(pos, p[cur][i]);
}
val ^= b[cur][i];
}
}
}
int query(int l, int r){
int ret = 0;
for(int i = 19; i >= 0; --i){
if((ret ^ b[r][i]) > ret && p[r][i] >= l) ret ^= b[r][i];
}
return ret;
}
int main(){
ios::sync_with_stdio(0); cin.tie(0);
cin >> n;
for(int i = 1; i <= n; ++i){
int tp; cin >> tp;
insert(i, i, tp);
}
cin >> m;
while(m--){
int l, r; cin >> l >> r;
int ret = query(l, r);
cout << ret << "\n";
}
return 0;
}