解析:
第K大数字问题,用线段树来求解。线段树每个节点保存当前编号的数出现的次数。每次查询从小到大第N-K+1个数(N为当前数的总数)。
AC代码
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#define ls 2*o
#define rs 2*o+1
using namespace std;
typedef long long ll;
const int N = 1000000 + 10;
int n, K;
int sumv[N << 2];
char cmd[3];
void build(int o, int L, int R) {
if(L == R) {
sumv[o] = 0;
return ;
}
int M = (L + R)/2;
build(ls, L, M);
build(rs, M+1, R);
sumv[o] = sumv[ls] + sumv[rs];
}
int p, v;
void modify(int o, int L, int R) {
if(L == R) {
sumv[o]++;
return ;
}
int M = (L + R)/2;
if(p <= M) modify(ls, L, M);
else modify(rs, M+1, R);
sumv[o] = sumv[ls] + sumv[rs];
}
void query(int o, int L, int R) {
if(L == R) {
printf("%d\n", L);
return;
}
int M = (L + R)/2;
if(sumv[rs] >= p) {
query(rs, M+1, R);
}else {
p -= sumv[rs];
query(ls, L, M);
}
}
int main() {
while(scanf("%d%d", &n, &K) != EOF) {
memset(sumv, 0, sizeof(sumv));
int x;
while(n--) {
scanf("%s", cmd);
if(cmd[0] == 'I') {
scanf("%d", &x);
p = x;
modify(1, 1, N);
}else {
p = K;
query(1, 1, N);
}
}
}
return 0;
}