https://codeforces.com/contest/1262/problem/D2
https://blog.csdn.net/A_Bright_CH/article/details/79979559
在树状数组种求第k大的数
#include <stdio.h>
#include <algorithm>
using namespace std;
struct node
{
int v,id;
bool operator<(const node &x)const{
return v==x.v?id<x.id:v>x.v;
}
}a[200005];
struct data
{
int k,pos,id;
bool operator<(const data &x)const{
return k<x.k;
}
}q[200005];
int n,c[200005],ans[200005],last[200005];
void add(int x){for(;x<=n;x+=x&(-x))c[x]+=1;}
int query(int k)
{
int cur=0;
for(int i=19;i>=0;i--) //为什么要逆序,这样相加才能正好走到第k-1大的位置
{
if((1<<i)+cur>n||c[cur+(1<<i)]>=k)continue;
cur+=1<<i;k-=c[cur]; //这过程是走到第k-1大的过程
} //第8大就是 4+2+1,因为c[8]可能大于k这样子如果
return cur+1; //去掉==的话,即return cur,我们就会返回k-1大的数
} //而!=k,这样我们得到无限逼近k大的数,+1即是第k大
int main()
{
int m,tim=0;
scanf("%d",&n);
for(int i=1;i<=n;i++) //输入的序列
{
scanf("%d",&a[i].v);
last[i]=a[i].v;
a[i].id=i;
}
sort(a+1,a+1+n);
scanf("%d",&m);
for(int i=1;i<=m;i++) //前k大,并且字典序最小,的第pos个数的值
{
scanf("%d %d",&q[i].k,&q[i].pos);
q[i].id=i;
}
sort(q+1,q+1+m); //按k的个数排序
for(int i=1;i<=m;i++)
{
while(tim<q[i].k)tim++,add(a[tim].id);
ans[q[i].id]=last[query(q[i].pos)];
}
for(int i=1;i<=m;i++)
printf("%d\n",ans[i]);
}