poj2104 K-th Number
K-th Number
#include<iostream> #include<cstdio> #include<algorithm> #define maxn 100001 using namespace std; int lc[maxn*18],rc[maxn*18],sum[maxn*18]; int n,m,a[maxn],hash[maxn],cnt,root[maxn]; int x,y,k; void discrete(){ sort(hash+1,hash+n+1); cnt=unique(hash+1,hash+n+1)-(hash+1); for(int i=1;i<=n;i++) a[i]=lower_bound(hash+1,hash+n+1,a[i])-hash; } int query(int x,int y,int l,int r,int k){ if(l==r)return l; int mid=(l+r)>>1; int tmp=sum[lc[y]]-sum[lc[x]]; if(tmp>=k)return query(lc[x],lc[y],l,mid,k); else return query(rc[x],rc[y],mid+1,r,k-tmp); } int tot; void build(int x,int &y,int l,int r,int v){ tot++;y=tot; sum[y]=sum[x]+1; if(l==r)return; int mid=(l+r)>>1; if(v<=mid){ rc[y]=rc[x]; build(lc[x],lc[y],l,mid,v); } else{ lc[y]=lc[x]; build(rc[x],rc[y],mid+1,r,v); } } int main(){ freopen("Cola.txt","r",stdin); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)scanf("%d",&a[i]),hash[i]=a[i]; discrete();//离散化 //建立n棵线段树 for(int i=1;i<=n;i++)build(root[i-1],root[i],1,cnt,a[i]); for(int i=1;i<=m;i++){ scanf("%d%d%d",&x,&y,&k); printf("%d\n",hash[query(root[x-1],root[y],1,cnt,k)]); } }