洛谷 p3834 主席树
题目链接:https://www.luogu.org/problem/P3834
主席树求静态区间第k小
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; #define maxn 200005 #define ll long long int T[maxn*20],L[maxn*20],R[maxn*20],sum[maxn*20],tot; ll a[maxn],b[maxn]; inline 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 mid=l+r>>1; if(x<=mid)L[rt]=update(L[pre],l,mid,x); else R[rt]=update(R[pre],mid+1,r,x); } return rt; } inline int query(int u,int v,int l,int r,int k) { if(l>=r)return l; int x=sum[L[v]]-sum[L[u]],mid=l+r>>1; if(x>=k)return query(L[u],L[v],l,mid,k); else return query(R[u],R[v],mid+1,r,k-x); } int main() { int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%lld",&a[i]); b[i]=a[i]; } sort(b+1,b+1+n); int len=unique(b+1,b+1+n)-b-1; tot=0; for(int i=1;i<=n;i++) { int pos=lower_bound(b+1,b+1+len,a[i])-b; T[i]=update(T[i-1],1,len,pos); } int l,r,k; for(int i=1;i<=m;i++) { scanf("%d%d%d",&l,&r,&k); printf("%lld\n",b[query(T[l-1],T[r],1,len,k)]); } return 0; }