题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=1261
解题思路:比较水的题,用离散化+树状数组求K小数即可,先用一次离线处理。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
const int maxn = 100005;
struct Node
{
char op[2];
int num;
}p[maxn];
int n,cnt,tree[maxn];
set<int> Set;
map<int,int> Map,Rev;
int lowbit(int x)
{
return x & -x;
}
void update(int x,int d)
{
while(x <= cnt)
{
tree[x] += d;
x += lowbit(x);
}
}
int sum(int x)
{
int ans = 0;
while(x > 0)
{
ans += tree[x];
x -= lowbit(x);
}
return ans;
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
cnt = 0;
Map.clear();
Rev.clear();
Set.clear();
memset(tree,0,sizeof(tree));
for(int i = 1; i <= n; i++)
{
scanf("%s",p[i].op);
scanf("%d",&p[i].num);
if(p[i].op[0] == 'I')
Set.insert(p[i].num);
}
for(set<int>::iterator it = Set.begin(); it != Set.end(); it++)
{
Map[*it] = ++cnt;
Rev[cnt] = *it;
}
for(int i = 1; i <= n; i++)
{
if(p[i].op[0] == 'I')
update(Map[p[i].num],1);
else
{
int l = 1,r = cnt,mid,ans = -1;
while(l <= r)
{
mid = (l + r) >> 1;
int tmp = sum(mid);
if(tmp >= p[i].num)
{
ans = mid;
r = mid - 1;
}
else l = mid + 1;
}
if(ans == -1) printf("-1\n");
else printf("%d\n",Rev[ans]);
}
}
}
return 0;
}