/* 求l,r这个死序列中第k小的数 */ #include <stdio.h> #include <algorithm> # include <string.h> using namespace std; # define lson l,m # define rson m+1,r # define N 100005 int a[N],Hash[N]; int T[N];///树祖宗节点的编号 int sum[N<<5];//数目 int L[N<<5];//左儿子的编号 int R[N<<5];//右儿子的编号 int tot; int build(int l,int r) { int rt=(++tot); sum[rt]=0; if(l<r) { int m=(l+r)>>1; L[rt]=build(lson); R[rt]=build(rson); } return rt; } int update(int pre,int l,int r,int x) { int rt=(++tot); L[rt]=L[pre]; R[rt]=R[pre]; sum[rt]=sum[pre]+1; if(l<r) { int m=(l+r)>>1; if(x<=m) L[rt]=update(L[pre],lson,x); else R[rt]=update(R[pre],rson,x); } return rt; } int query(int u,int v,int l,int r,int k) { if(l>=r) return l; int m=(l+r)>>1; int num=sum[L[v]]-sum[L[u]]; if(num>=k) return query(L[u],L[v],lson,k); else return query(R[u],R[v],rson,k-num); } int main() { int n,m,i; while(~scanf("%d%d",&n,&m)) { tot=0; for(i=1;i<=n;i++) { scanf("%d",&a[i]); Hash[i]=a[i]; } sort(Hash+1,Hash+n+1);//离散 int size=unique(Hash+1,Hash+n+1)-Hash-1; T[0]=build(1,size);//裸树 for(i=1;i<=n;i++)//在T[0]的基础上建n棵树 { int x=lower_bound(Hash+1,Hash+size+1,a[i])-Hash; T[i]=update(T[i-1],1,size,x); } while(m--) { int l,r,k; scanf("%d%d%d",&l,&r,&k); int x=query(T[l-1],T[r],1,size,k); printf("%d\n",Hash[x]); } } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文:http://blog.csdn.net/lp_opai/article/details/47111197