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
| #include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <vector> using namespace std;
const int maxN = 1e5 + 7; int T, n, m, a[maxN], ind[maxN]; int ls[maxN << 5], rs[maxN << 5], rt[maxN << 5], tot, sum[maxN << 5], len;
inline int getId(int x) { return lower_bound(ind + 1, ind + 1 + len, x) - ind; }
int build(int l, int r) { int root = ++tot; if(l == r) return root; int mid = (l + r) >> 1; ls[root] = build(l, mid); rs[root] = build(mid + 1, r); return root; }
int update(int k, int l, int r, int root) { int dir = ++tot; ls[dir] = ls[root]; rs[dir] = rs[root]; sum[dir] = sum[root] + 1; if(l == r) return dir; int mid = (l + r) >> 1; if(k <= mid) ls[dir] = update(k, l, mid, ls[dir]); else rs[dir] = update(k, mid + 1, r, rs[dir]); return dir; }
int query(int u, int v, int l, int r, int k) { int mid = (l + r) >> 1, x = sum[ls[v]] - sum[ls[u]]; if(l == r) return l; if(k <= x) return query(ls[u], ls[v], l, mid, k); else return query(rs[u], rs[v], mid + 1, r, k - x); }
int main() { scanf("%d", &T); while(T--) { tot = 0; scanf("%d", &n); for(int i = 1; i <= n; ++i) scanf("%d", &a[i]); memcpy(ind, a, sizeof a); sort(ind + 1, ind + 1 + n); len = unique(ind + 1, ind + 1 + n) - ind - 1; rt[0] = build(1, len); for(int i = 1; i <= n; ++i) rt[i] = update(getId(a[i]), 1, len, rt[i - 1]); scanf("%d", &m); while(m--) { int l, r; scanf("%d%d", &l, &r); vector<int> s; int ans = 0x7f7f7f7f; for(int i = 1; i <= min(r - l + 1, 31); ++i) s.push_back(ind[query(rt[l - 1], rt[r], 1, len, i)]); for(int i = 0; i < s.size(); ++i) for(int j = i + 1; j < s.size(); ++j) ans = min(ans, s[i] | s[j]); printf("%d\n", ans); } } return 0; }
|