主席树
#include<cstdio> #include<cstring> #include<algorithm> #define mid (l+r)/2 using namespace std; const int N = 200010; int n, q, m, cnt = 0; int a[N], b[N], T[N]; int sum[N<<5], L[N<<5], R[N<<5]; inline int build(int l, int r) { int rt = ++ cnt; sum[rt] = 0; if (l < r){ L[rt] = build(l, mid); R[rt] = build(mid+1, r); } return rt; } inline int update(int pre, int l, int r, int x) { int rt = ++ cnt; L[rt] = L[pre]; R[rt] = R[pre]; sum[rt] = sum[pre]+1; if (l < r){ if (x <= mid) L[rt] = update(L[pre], l, mid, x); else R[rt] = update(R[pre], mid+1, r, x); } return rt; } inline int query(int u, int v, int l, int r, int k) { if (l >= r) return l; int x = sum[L[v]] - sum[L[u]]; if (x >= k) return query(L[u], L[v], l, mid, k); else return query(R[u], R[v], mid+1, r, k-x); } int main() { scanf("%d%d", &n, &q); for (int i = 1; i <= n; i ++){ scanf("%d", &a[i]); b[i] = a[i]; } sort(b+1, b+1+n); m = unique(b+1, b+1+n)-b-1; T[0] = build(1, m); for (int i = 1; i <= n; i ++){ int t = lower_bound(b+1, b+1+m, a[i])-b; T[i] = update(T[i-1], 1, m, t); } while (q --){ int x, y, z; scanf("%d%d%d", &x, &y, &z); int t = query(T[x-1], T[y], 1, m, z); printf("%d\n", b[t]); } return 0; }
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
const int N = 100000 + 5;
vector<int>node[N << 2];
int T, n, q, ql, qr, ans, k, sz;
int a[N], b[N];
inline int read(){//快速读入是邪教
char c;
int ret = 0;
int sgn = 1;
do{c = getchar();}while((c < '0' || c > '9') && c != '-');
if(c == '-') sgn = -1; else ret = c - '0';
while((c = getchar()) >= '0' && c <= '9') ret = ret * 10 + (c - '0');
return sgn * ret;
}
void Build(int o, int l, int r){
node[o].clear();
if(l == r){
node[o].push_back(a[l]);
return ;
}
int m = (l + r) >> 1;
Build(o << 1, l, m);
Build(o << 1|1, m + 1, r);
node[o].resize(r - l + 1);
merge(node[o<<1].begin(), node[o<<1].end(), node[o<<1|1].begin(), node[o<<1|1].end(), node[o].begin());
}
int query(int o, int l, int r, int x){
//if(ql > r || qr < l) return 0;
if(ql <= l && qr >= r) return upper_bound(node[o].begin(), node[o].end(), x) - node[o].begin();
int m = (l + r) >> 1;
int ret = 0;
if(ql <= m)ret += query(o << 1, l, m, x);
if(qr > m)ret += query(o << 1|1, m + 1, r, x);
return ret;
}
void work(){
//ql = read();
//qr = read();
//k = read();
scanf("%d%d%d", &ql, &qr, &k);
int lt = 1, rt = sz;
while(lt <= rt){
int md = (lt + rt) >> 1;
if(query(1, 1, n, b[md]) >= k)rt = md - 1;
else lt = md + 1;
}
printf("%d\n", b[rt+1]);
}
int main(){
scanf("%d", &T);
while(T--){
scanf("%d%d", &n, &q);
//n = read();
//q = read();
//for(int i = 1; i <= n; i ++) a[i] = b[i] = read();
for(int i = 1; i <= n; i ++)scanf("%d", a + i), b[i] = a[i];
Build(1, 1, n);
sort(b + 1, b + n + 1);
sz = unique(b + 1, b + n + 1) - (b + 1);
while(q --)work();
}
return 0;
}

浙公网安备 33010602011771号