src : http://poj.org/problem?id=2104
ac代码:
#include <bits/stdc++.h> using namespace std; #define per(i,a,b) for(int i=a;i<=b;i++) #define MP make_pair typedef pair<int,int> PII; typedef vector<int> VI; const int inf =0x3f3f3f; #define siz 100005 int n,m,totn,a[siz],b[siz],Nnum=0,root[siz];//b是离散化的点 struct node { int lc,rc,s; }Node[siz*20]; void Insert(int l,int r,int pre,int &now,int pos) { now=++Nnum; Node[now]=Node[pre]; Node[now].s++;//区间内的个数+1 if(l==r)return; int mid=(l+r)>>1; if(pos<=mid)Insert(l,mid,Node[pre].lc,Node[now].lc,pos); else Insert(mid+1,r,Node[pre].rc,Node[now].rc,pos); } int query(int l,int r,int x,int y,int k)//[x,y] k_th 这个函数里的xy已经是xy对应的root了! { if(l==r)return l; int mid=(l+r>>1); int sum=Node[Node[y].lc].s-Node[Node[x].lc].s;//用于判断第k个在左子树还是右子树 //sum就表示[x,y]阶段内[l,r]的左子树的个数 if(sum>=k)query(l,mid,Node[x].lc,Node[y].lc,k); else query(mid+1,r,Node[x].rc,Node[y].rc,k-sum); } int main() { totn=0; scanf("%d %d",&n,&m); per(i,1,n){scanf("%d",&a[i]);b[i]=a[i];} sort(b+1,b+1+n); totn=unique(b+1,b+1+n)-b-1; cerr<<"tot:"<<totn<<endl;// per(i,1,n) Insert(1,totn,root[i-1],root[i],lower_bound(b+1,b+1+n,a[i])-b); int x,y,k; for(int i=1;i<=m;i++){ scanf("%d %d %d",&x,&y,&k); printf("%d ",b[query(1,totn,root[x-1],root[y],k)]); } return 0; }