空间大小:n*lgn
复杂度:建树n*lgn 查询lgn
#include <cstdio> #include <iostream> #include <algorithm> using namespace std; const int maxn=1e5+5; struct Node { int L,R,num; }tree[20*maxn]; struct Rank { int x,id; bool operator <(Rank a)const { return x<a.x; } }ran[maxn]; int root[maxn],num[maxn]; int cnt=1; void updata(int x,int &rt,int a,int b)//建树操作 { tree[cnt++]=tree[rt];//新建子树并且复制 rt=cnt-1; tree[rt].num++; if(a==b)return; int mid=(a+b)/2; if(x<=mid) updata(x,tree[rt].L,a,mid); else updata(x,tree[rt].R,mid+1,b); } int quer(int a,int b,int k,int s,int o)//查询操作,查询a—b区间,第k位置,属性为s—o的节点 { int d=tree[tree[b].L].num-tree[tree[a].L].num; if(s==o)return s; if(k<=d) return quer(tree[a].L,tree[b].L,k,s,(s+o)/2); else return quer(tree[a].R,tree[b].R,k-d,(s+o)/2+1,o); } int main() { int n,m; cin>>n>>m; for(int i=1;i<=n;i++) { scanf("%d",&ran[i].x); ran[i].id=i;//ran和num的作用是离散处理 } sort(ran+1,ran+n+1); for(int i=1;i<=n;i++) { num[ran[i].id]=i; } for(int i=1;i<=n;i++) { root[i]=root[i-1];//复制上一个树 updata(num[i],root[i],1,n); } for(int i=1;i<=m;i++) { int l,r,k; scanf("%d %d %d",&l,&r,&k); printf("%d ",ran[quer(root[l-1],root[r],k,1,n)].x); } return 0; }