P3834 【模板】可持久化线段树 2(主席树)
静态查询区间第k小
离散化挂了.....
注意$|a_i|<=10^9$,所以离散化的时候$b[0]=-2e9$以防止$0$被忽略录入
#include<cstdio> #include<algorithm> using namespace std; const int N=200003; int n,u,m,a[N],b[N],rt[N],lc[N*18],rc[N*18],s[N*18],U; #define mid (l+r)/2 void Add(int &o,int e,int l,int r,int k){ s[o=++U]=s[e]+1,lc[o]=lc[e],rc[o]=rc[e]; if(l==r) return ; if(k<=mid) Add(lc[o],lc[e],l,mid,k); else Add(rc[o],rc[e],mid+1,r,k); } int Ask(int o,int e,int l,int r,int k){ if(l==r) return l; int w=s[lc[o]]-s[lc[e]]; if(k<=w) return Ask(lc[o],lc[e],l,mid,k); else return Ask(rc[o],rc[e],mid+1,r,k-w); } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;++i) scanf("%d",&a[i]),b[i]=a[i]; sort(b+1,b+n+1); b[0]=-2e9; for(int i=1;i<=n;++i) if(b[i]!=b[i-1]) b[++u]=b[i]; for(int i=1;i<=n;++i) Add(rt[i],rt[i-1],1,u,lower_bound(b+1,b+u+1,a[i])-b); for(int i=1,L,R,k;i<=m;++i){ scanf("%d%d%d",&L,&R,&k); printf("%d\n",b[Ask(rt[R],rt[L-1],1,u,k)]); } return 0; }