裸的主席树,可以见我的上一篇博客,或者见=>seter.is-programmer.com/posts/31907.html
AC代码如下:
#include<iostream> #include<cstdio> #include<algorithm> #define N 100005 using namespace std; int n,m,cnt,trtot,a[N],val[N],num[N],rt[N],ls[N*80],rs[N*80],sum[N*80]; int find(int x){ int l=1,r=cnt; while (l<r){ int mid=(l+r)>>1; if (val[mid]<x) l=mid+1; else r=mid; } return l; } void ins(int l,int r,int x,int &y,int v){ y=++trtot; sum[y]=sum[x]+1; if (l==r) return; int mid=(l+r)>>1; if (v<=mid){ rs[y]=rs[x]; ins(l,mid,ls[x],ls[y],v); } else{ ls[y]=ls[x]; ins(mid+1,r,rs[x],rs[y],v); } } int qry(int x,int y,int k){ x=rt[x-1]; y=rt[y]; int l=1,r=cnt; while (l<r){ int mid=(l+r)>>1,tmp=sum[ls[y]]-sum[ls[x]]; if (tmp>=k){ r=mid; x=ls[x]; y=ls[y]; } else{ l=mid+1; x=rs[x]; y=rs[y]; k-=tmp; } } return l; } int main(){ scanf("%d%d",&n,&m); int i; for (i=1; i<=n; i++){ scanf("%d",&a[i]); num[i]=a[i]; } sort(num+1,num+n+1); for (i=1; i<=n; i++) if (i==1 || num[i]!=num[i-1]) val[++cnt]=num[i]; for (i=1; i<=n; i++) ins(1,cnt,rt[i-1],rt[i],find(a[i])); while (m--){ int x,y,z; scanf("%d%d%d",&x,&y,&z); printf("%d\n",val[qry(x,y,z)]); } return 0; }
by lych
2016.2.11