题目大意:有$n$个数,$m$个询问,每个询问给你$b;x;l;r$表示在区间$[l,r]$中寻找一个数$p$,使得$boplus(a+x)$最大
题解:主席树,每一位贪心,若$b$第$i$位为$1$,就询问$[l,r]$中是否有数在$[ans-x,ans-x-1+2^i]$范围内($ans$为前几位贪心出来的最优的$a+x$)
卡点:无
C++ Code:
#include <cstdio> #include <cctype> namespace R { int x, ch; inline int read() { ch = getchar(); while (isspace(ch)) ch = getchar(); for (x = ch & 15, ch = getchar(); isdigit(ch); ch = getchar()) x = x * 10 + (ch & 15); return x; } } using R::read; #define maxn 200010 #define M 17 #define N (maxn * (M + 2)) const int maxl = 0, maxr = 99999; namespace SgT { int V[N], lc[N], rc[N], idx; void insert(int &rt, int l, int r, int num) { lc[++idx] = lc[rt], rc[idx] = rc[rt], V[idx] = V[rt] + 1, rt = idx; if (l == r) return ; int mid = l + r >> 1; if (num <= mid) insert(lc[rt], l, mid, num); else insert(rc[rt], mid + 1, r, num); } bool query(int rtL, int rtR, int l, int r, int L, int R) { if (R < l || L > r) return false; if (L <= l && R >= r) return V[rtR] - V[rtL]; int mid = l + r >> 1; if (L <= mid && query(lc[rtL], lc[rtR], l, mid, L, R)) return true; if (R > mid && query(rc[rtL], rc[rtR], mid + 1, r, L, R)) return true; return false; } } int n, m, rt[maxn]; int main() { n = read(), m = read(); for (int i = 1; i <= n; i++) { SgT::insert(rt[i] = rt[i - 1], maxl, maxr, read()); } while (m --> 0) { int b = read(), x = read(), l = read(), r = read(); int ans = 0; for (int i = M; ~i; i--) { if (b >> i & 1) { if (!SgT::query(rt[l - 1], rt[r], maxl, maxr, ans - x, ans - x - 1 + (1 << i))) ans += 1 << i; } else { if (SgT::query(rt[l - 1], rt[r], maxl, maxr, ans - x + (1 << i), ans - x - 1 + (2 << i))) ans += 1 << i; } } printf("%d ", ans ^ b); } return 0; }