标签:第k小 ... lower turn pac 题目 注释 UI upd
题目描述
看到很短的题目会让人心情愉悦,所以给出一个长度为N的序列A1,A2,A3,...,AN,
现在有M个询问,每个询问都是Ai...Aj中第k小的数等于多少。
询问Ai...Aj中第k小的数等于多少。
共输出M行,第i行输出第i个询问的答案。
4 3
4 1 2 3
1 3 1
2 4 3
1 4 4
#include <algorithm> #include <cstdio> #define N 100500 using namespace std; struct cmt { int l,r,size; }tr[N*30]; int n,m,rt[N],tot,a[N],b[N],size; int build(int l,int r) { int now=++tot; tr[now].size=0; if(l==r) return now; int mid=(l+r)>>1; tr[now].l=build(l,mid); tr[now].r=build(mid+1,r); return now; } inline int Rank(int x) { return lower_bound(b+1,b+1+size,x)-b; } void update(int l,int r,int x,int &y,int t) { y=++tot; tr[y].size=tr[x].size+1; if(l==r) return; tr[y].l=tr[x].l; tr[y].r=tr[x].r; int mid=(l+r)>>1; if(t<=mid) update(l,mid,tr[x].l,tr[y].l,t); else update(mid+1,r,tr[x].r,tr[y].r,t); } int ask(int l,int r,int lx,int rx,int k) { if(l==r) return l; int mid=(l+r)>>1; if(tr[tr[rx].l].size-tr[tr[lx].l].size>=k) return ask(l,mid,tr[lx].l,tr[rx].l,k); else {k-=tr[tr[rx].l].size-tr[tr[lx].l].size;return ask(mid+1,r,tr[lx].r,tr[rx].r,k);} } int Main() { freopen("kth.in","r",stdin); freopen("kth.out","w",stdout); scanf("%d%d",&n,&m); for(int i=1;i<=n;++i) scanf("%d",&a[i]),b[i]=a[i]; sort(b+1,b+1+n); size=unique(b+1,b+1+n)-b-1; rt[0]=build(1,size); for(int i=1;i<=n;++i) update(1,size,rt[i-1],rt[i],Rank(a[i])); for(int l,r,k;m--;) { scanf("%d%d%d",&l,&r,&k); printf("%d\n",b[ask(1,size,rt[l-1],rt[r],k)]); } return 0; } int sb=Main(); int main(int argc,char *argv[]) {;}
标签:第k小 ... lower turn pac 题目 注释 UI upd
原文地址:http://www.cnblogs.com/ruojisun/p/7413886.html