题意:没有修改的区间第k小(题目中的第k大是骗人的)。
题解:没有修改的主席树可以做。
/*
主席树求区间第k小,没有修改操作
*/
#include <iostream>
#include <stdio.h>
#include <vector>
#include <algorithm>
using namespace std;
#define MAXN 100100
class TreeNode{
public:
TreeNode *ch[2];
int size;
void update(){
size = 0;
if(ch[0]){
size += ch[0]->size;
}
if(ch[1]){
size += ch[1]->size;
}
}
};
TreeNode *null;
TreeNode *root[MAXN];
TreeNode q[MAXN*20];
int q_s;
void make_node(TreeNode *&nt,TreeNode *&ot,int l,int r,int va){
nt = &q[q_s++];//新树
int m =(l+r)>>1;
if(l==r){
nt->size=ot->size+1;
return;
}
if(va<=m){
make_node(nt->ch[0],ot->ch[0],l,m,va);
nt->ch[1]=ot->ch[1];
nt->update();
}else{
make_node(nt->ch[1],ot->ch[1],m+1,r,va);
nt->ch[0]=ot->ch[0];
nt->update();
}
}
int a[MAXN];
int rd[MAXN];
void find(TreeNode *<,TreeNode *&rt,int l,int r,int k){
if(l==r){
printf("%d\n",rd[l-1]);
return;
}
int m = (l+r)>>1;
int ls = 0;
ls+=rt->ch[0]->size;
ls-=lt->ch[0]->size;
if(ls>=k){
find(lt->ch[0],rt->ch[0],l,m,k);
}else{
find(lt->ch[1],rt->ch[1],m+1,r,k-ls);
}
}
int main() {
null = new TreeNode();
null->ch[0]=null->ch[1]=null;
root[0]=null;
int T;
scanf(" %d",&T);
while(T--){
int n,m;
scanf(" %d %d",&n,&m);
for(int i=1;i<=n;i++){
scanf(" %d",&a[i]);
rd[i-1] = a[i];
}
sort(rd,rd+n);
int size = unique(rd,rd+n)-rd;
for(int i=1;i<=n;i++){
a[i] = lower_bound(rd,rd+size,a[i])-rd+1;
}
q_s = 0;
for(int i=1;i<=n;i++){
make_node(root[i],root[i-1],1,size,a[i]);
}
for(int i=1;i<=m;i++){
int lp,rp,k;
scanf(" %d %d %d",&lp,&rp,&k);
find(root[lp-1],root[rp],1,size,k);
}
}
delete null;
return 0;
}