标签:contest define print can turn space str get scanf
题意
给定序列,$q(1\leq q \leq 100000) $次询问,每次查询给定区间内的最大异或子集。
思路
涉及到最大异或子集肯定从线性基角度入手。将询问按右端点排序后离线处理询问,对线性基的每一位贪心的保留靠后的。
代码
#include <bits/stdc++.h> #define DBG(x) cerr << #x << " = " << x << endl; using namespace std; const int N = 500000 + 5; int n, m, a[N], ans[N], L = 1; struct node { int l, r, id; bool operator < (const node & a) const { if(r != a.r) return r < a.r; return l < a.l; } }b[N]; struct base { int b[21], pos[21]; void add(int x, int id) { for(int i = 20; i >= 0; i--) { if((x >> i) & 1) { if(!pos[i]) { b[i] = x, pos[i] = id; return; } if(id > pos[i]) {swap(x, b[i]); swap(id, pos[i]);} x ^= b[i]; } } } int query(int id) { int res = 0; for(int i = 20; i >= 0; i--) { if(pos[i] >= id && (res ^ b[i]) > res) res ^= b[i]; } return res; } }bs; 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", &b[i].l, &b[i].r), b[i].id = i; sort(b + 1, b + 1 + m); for(int i = 1; i <= m; i++) { while(L <= b[i].r) bs.add(a[L], L), L++; ans[b[i].id] = bs.query(b[i].l); } for(int i = 1; i <= m; i++) printf("%d\n", ans[i]); return 0; }
标签:contest define print can turn space str get scanf
原文地址:https://www.cnblogs.com/DuskOB/p/10575362.html