给定一个长度为 n n n序列,一共 q q q次询问,每次询问给定区间 [ l , r ] [l,r] [l,r]和一个数 k k k,求 l l l到 r r r区间内所有大于等于 k k k的数相与的结果.
将 a i a_i ai按照从大到小的顺序插入线段树,插入的时候动态查询区间 [ l , r ] [l,r] [l,r]的按位与的和即可。
//std
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn = 1e5 + 7, inf = (1 << 20) - 1;
typedef long long ll;
int res[maxn << 2], sum[maxn << 2];
#define lson rt << 1
#define rson rt << 1 | 1
void push_up(int rt){
sum[rt] = sum[lson] + sum[rson];
res[rt] = res[lson] & res[rson];
}
void build(int rt, int l, int r){
res[rt] = inf; sum[rt] = 0;
if(l == r) return ;
int mid = (l + r) >> 1;
build(lson, l, mid); build(rson, mid + 1, r);
}
void update(int rt, int l, int r, int pos, int v){
if(l == pos && r == pos){
//printf("ins %d %d\n", l, v);
sum[rt]++;
res[rt] = v;
return ;
}
int mid = (l + r) >> 1;
if(pos <= mid) update(lson, l, mid, pos, v);
else update(rson, mid + 1, r, pos, v);
push_up(rt);
}
int num, ans;
void query(int rt, int l, int r, int ql, int qr){
if(l == ql && r == qr){
//printf("que %d %d\n", l, r);
num += sum[rt];
ans &= res[rt];
return ;
}
int mid = (l + r) >> 1;
if(qr <= mid) query(lson, l, mid, ql, qr);
else if(ql > mid) query(rson, mid + 1, r, ql, qr);
else{
query(lson, l, mid, ql, mid);
query(rson, mid + 1, r, mid + 1, qr);
}
}
int n, q, a[maxn], Ans[maxn];
vector<int> G[maxn];
struct node{
int l, r, id;
};
vector<node> Q[maxn];
int main(){
scanf("%d%d", &n, &q);
for(int i = 1; i <= n; i++){
scanf("%d", a + i);
G[a[i]].push_back(i);
}
for(int i = 1; i <= q; i++){
int l, r, k;
scanf("%d%d%d", &l, &r, &k);
Q[k].push_back(node{l, r, i});
}
build(1, 1, n);
for(int i = maxn - 1; i >= 0; i--){
for(int &idx : G[i]) update(1, 1, n, idx, i);
for(node &p : Q[i]){
//printf("i %d %d %d\n", i, p.l, p.r);
num = 0; ans = inf;
query(1, 1, n, p.l, p.r);
//printf("num %d ans %d\n", num, ans);
if(num > 0) Ans[p.id] = ans;
else Ans[p.id] = -1;
}
}
for(int i = 1; i <= q; i++) printf("%d\n", Ans[i]);
return 0;
}