主席树。
主席树复习,这道题是主席树的经典入门了吧。。
无修改区间第k大。
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int maxn = 200000 + 10; const int maxm = 5000000 + 10; /* void build(int &x,int L,int R) { if(!x) x=++vid; if(L==R) return; int mid = (L+R)>>1; build(lc[x],L,mid); build(rc[x],mid+1,R); }*/ int root[maxn]; int lc[maxm],rc[maxm],s[maxm],vid; int n,m,q,cur; int a[maxn],t[maxn]; void modify(int &x,int y,int L,int R,int pos,int val=1) { x=++vid; s[x]=s[y]+val; lc[x]=lc[y]; rc[x]=rc[y]; if(L==R) return; int mid = (L+R)>>1; if(pos<=mid) modify(lc[x],lc[y],L,mid,pos); else modify(rc[x],rc[y],mid+1,R,pos); } int query(int x,int y,int k) { int l=1,r=m; while(l<r) { cur=s[lc[x]]-s[lc[y]]; int mid=(l+r)>>1; if(k<=cur) { x=lc[x]; y=lc[y]; r=mid; } else { x=rc[x]; y=rc[y]; l=mid+1; k-=cur; } } return l; } int l,r,k; int main() { scanf("%d%d",&n,&q); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); t[i]=a[i]; } //printf("test\n"); sort(t+1,t+n+1); m=unique(t+1,t+n+1)-(t+1); for(int i=1;i<=n;i++) a[i]=lower_bound(t+1,t+m+1,a[i])-t; for(int i=1;i<=n;i++) modify(root[i],root[i-1],1,m,a[i]); while(q--) { scanf("%d%d%d",&l,&r,&k); printf("%d\n",t[query(root[r],root[l-1],k)]); } return 0; }
时间: 2024-12-22 12:22:11