1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
| #include <set> #include <map> #include <stack> #include <queue> #include <ctime> #include <cmath> #include <cstdio> #include <vector> #include <bitset> #include <string> #include <cstring> #include <sstream> #include <cstdlib> #include <iostream> #include <algorithm> #include <functional> #define eps 1e-8 #define PI acos(-1.0)
using namespace std; const int maxn = 100005; int a[maxn ], b[maxn],rt[maxn]; typedef long long ll; struct node{ int l, r, sum; }tree[maxn * 50]; int tot;
void build(int &o, int l, int r ) { o = ++tot; tree[o].sum = 0; if(l == r) return ; int mid = (l + r) >> 1; build(tree[o].l , l, mid); build(tree[o].r, mid + 1, r); }
void update(int &o, int last, int l, int r, int pos) { o =++tot; tree[o].l = tree[last].l; tree[o].r = tree[last].r; tree[o].sum = tree[last].sum + 1; if(l == r) return; int mid = (l + r) >> 1; if(pos <= mid) update(tree[o].l, tree[last].l, l, mid, pos); else update(tree[o].r , tree[last].r, mid + 1, r, pos); }
int sum ; void query(int o, int last, int l, int r, int left, int right) { if(left > b[r] || right < b[l]) return; if(left <= b[l] && right >= b[r]) { sum += tree[o].sum - tree[last].sum; return; } int mid = (l + r) >> 1; query(tree[o].l, tree[last].l, l, mid, left, right); query(tree[o].r, tree[last].r, mid +1, r, left, right);
} int main() { int T,n,Q,L,R,K,P; scanf("%d",&T); while(T--) { tot = 0; scanf("%d %d",&n,&Q); for(int i = 1; i <= n; ++i) { scanf("%d",&a[i]); b[i] = a[i]; } sort(b + 1, b + n + 1); int N = unique(b + 1, b + n + 1) - b - 1; build(rt[0],1 ,N); for(int i = 1; i <= n; ++i) { a[i] = lower_bound(b + 1, b + N + 1, a[i]) - b; update(rt[i], rt[i - 1], 1, N, a[i]); } int res = 0; while(Q--) { scanf("%d %d %d %d",&L,&R,&P,&K); L ^= res, R ^= res, K ^= res, P ^= res; int l = 0, r = 1000005; while(l <= r) { int mid = (l + r) / 2; sum = 0; query(rt[R], rt[L - 1], 1, N, P - mid, P + mid); if(sum >= K){ r = mid - 1; } else l = mid + 1; } cout << l << '\n'; res = l; } } }
|