萌新刚学OI(((2012−0712+(0x66ccff)16+(0712)8(1)2(66ccff)16×(20120712)8)−2023.10.29+(0712)81)7.12)0x66ccff1天,可持久化线段树求调
80pts,MLE两个点
#include<bits/stdc++.h>
#define mid (l+r)/2
#define int long long
using namespace std;
int n,q,m,cnt = 0;
int a[0x66ccf],b[0x66ccf],T[0x66ccf];
int sum[0x66ccff],L[0x66ccff],R[0x66ccff];
inline int read(){
int s = 0,w = 1;char ch = getchar();
while(ch<'0'||ch>'9'){ if(ch == '-') w = -1;ch = getchar();}
while(ch>='0'&&ch<='9'){ s = s*10+ch-'0';ch = getchar();}
return s*w;
}
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 change(int q, int l, int r, int x){
int rt=++cnt;
L[rt]=L[q];
R[rt]=R[q];
sum[rt]=sum[q]+1;
if(l<r){
if(x<=mid) L[rt]=change(L[q],l,mid,x);
else R[rt]=change(R[q],mid+1,r,x);
}
return rt;
}
inline int ask(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 ask(L[u], L[v], l, mid, k);
return ask(R[u], R[v], mid+1, r, k-x);
}
signed main(){
n=read(),q=read();
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] = change(T[i-1], 1, m, t);
}
while(q--){
int x=read(),y=read(),z=read();
int t = ask(T[x-1], T[y], 1, m, z);
cout<<b[t]<<endl;
}
}