题目:主席树
思路:某位大佬的博客
代码:
using namespace std;
#define maxn (200000<<5)
#define read(x) scanf("%d",&x)
#define mid (L+R)/2
int n,T,m;
int c[maxn+5]; //离散化前
int b[maxn+5],mp[maxn+5]; //离散化用
int a[maxn+5]; //离散化后
int rt[maxn+5]; //第i个数对应的根节点
struct Node{
int x,lch,rch;
};
struct HJTbst{
Node node[maxn+5];
int P,cnt;
void build(int& o,int L,int R) {
o=++cnt;
if(L==R) return ;
build(node[o].lch,L,mid);
build(node[o].rch,mid+1,R);
}
int update(int o,int L,int R) {
cnt++; //新建节点
node[cnt].lch=node[o].lch,node[cnt].rch=node[o].rch;
node[cnt].x=node[o].x+1;
if(L==R) return cnt;
int och=cnt;
if(P<=mid) node[och].lch=update(node[och].lch,L,mid);
else node[och].rch=update(node[och].rch,mid+1,R);
return och;
}
int query(int qL,int qR,int L,int R,int K) {
int x=node[node[qR].lch].x-node[node[qL].lch].x;
if(L==R) return L;
if(x>=K) return query(node[qL].lch,node[qR].lch,L,mid,K);
else return query(node[qL].rch,node[qR].rch,mid+1,R,K-x);
}
} bst ;
int main() {
read(n),read(T);
for(int i=1;i<=n;i++) {
read(c[i]),b[i]=c[i];
}
sort(b+1,b+n+1); //离散化
m=unique(b+1,b+n+1)-b-1;
for(int i=1;i<=m;i++) mp[b[i]]=i;
for(int i=1;i<=n;i++) a[i]=mp[c[i]];
bst.build(rt[0],1,m); //建树
for(int i=1;i<=n;i++) {
bst.P=a[i];
rt[i]=bst.update(rt[i-1],1,m);
}
while(T--) {
int x,y,z;
read(x),read(y),read(z);
printf("%d\n",b[bst.query(rt[x-1],rt[y],1,m,z)]);
}
return 0;
}