题目来源:URAL 1439. Battle with You-Know-Who
题意:开始有数列1, 2, 3, ... L k输出第k大的数 D k删除第k大的数
思路:treap树插入删除的数 每次二分查找第k大的数为mid 查询treap小于等于mid的数有y个 那么mid应该是第mid-y大的数 与k比较 继续二分
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;
const int maxm = 100010;
int ch[maxm][2], r[maxm], val[maxm], sum[maxm], num[maxm], cnt, root;
void Node(int &rt, int x){
rt = ++cnt;
ch[rt][0] = ch[rt][1] = 0;
r[rt] = rand();
val[rt] = x;
if(cnt > 1)
{
sum[rt] = 1;
num[rt] = 1;
}
else
{
sum[rt] = 0;
num[rt] = 0;
}
}
void maintain(int rt){
sum[rt] = sum[ch[rt][0]]+sum[ch[rt][1]]+num[rt];
}
void init()
{
ch[0][0] = ch[0][1] = 0;
r[0] = (1LL<<31)-1;
val[0] = 0;
sum[0] = 0;
cnt = 0;
root = 0;
Node(root, 2000000001);
}
void rotate(int &rt, int d){
int k = ch[rt][d^1]; ch[rt][d^1] = ch[k][d]; ch[k][d] = rt;
maintain(rt); maintain(k); rt = k;
}
void insert(int &rt, int x){
if(!rt){
Node(rt, x);
return;
}
else{
if(x == val[rt])
num[rt]++;
else
{
int d = x < val[rt] ? 0 : 1;
insert(ch[rt][d], x);
if(r[ch[rt][d]] < r[rt]) rotate(rt, d^1);
}
}
maintain(rt);
}
/*void remove(int &rt, int x){
if(val[rt] == x){
val[rt]--;
if(!val[rt]){
if(!ch[rt][0] && !ch[rt][1])
{
rt = 0;
return;
}
else{
int d = r[ch[rt][0]] > r[ch[rt][1]] ? 1 : 0;
rotate(rt, d);
remove(ch[rt][d], x);
}
else{
}
}
}
else
remove(ch[rt][x>val[rt]], x);
maintain(rt);
}*/
int kth(int rt, int k){
if(rt == 0)
return 0;
if(val[rt] <= k)
return sum[ch[rt][0]]+num[rt]+kth(ch[rt][1], k);
return kth(ch[rt][0], k);
}
int main()
{
int n, m;
while(scanf("%d %d", &n, &m) != EOF)
{
init();
while(m--)
{
char s[10];
int x;
scanf("%s %d", s, &x);
int l = 1, r = n, ans;
//printf("****%d\n", kth(root, 10));
while(l < r)
{
int mid = (l + r) >> 1;
int y = kth(root, mid);
if(x > mid-y)
{
l = mid+1;
ans = mid+1;
}
else
{
r = mid;
}
//printf("***%d\n", y);
}
if(s[0] == 'L')
{
printf("%d\n", l);
}
else
{
//int y = kth(root, x);
insert(root, l);
}
}
}
return 0;
}