題目大意: 給定n個操作,操作分兩種,插入和查詢第k大的數。n<=1000000
解題思路:因為本題沒有刪除操作,所以變得特別簡單,只需要維護一個大小為k的小頂堆即可。
但是如果有刪除操作,就變地復雜了,所以用SBT寫了這道題,怒寫2遍,明天晚上黃金十點半再寫三遍,測模版的沒什麼好說的。
測試數據:
8 3
I 1
I 2
I 3
Q
I 5
Q
I 4
Q
C艹代碼:
[cpp]
#include <stdio.h>
#include <string.h>
#define MAX 1000010
int n,m;
struct SBT {
int left,right,size,key;
void Init() {
left = right = 0;
size = 1;
}
}a[MAX];
int tot,root;
void left_rotate(int &t) {
int k = a[t].right;
a[t].right = a[k].left;
a[k].left = t;
a[k].size = a[t].size;
a[t].size = a[a[t].left].size + a[a[t].right].size + 1;
t = k;
}
void right_rotate(int &t) {
int k = a[t].left;
a[t].left = a[k].right;
a[k].right = t;
a[k].size = a[t].size;
a[t].size = a[a[t].left].size + a[a[t].right].size + 1;
t = k;
}
void maintain(int &t,int flag) {
if (flag == 0) {
if (a[a[a[t].left].left].size > a[a[t].right].size)
right_rotate(t);
else if (a[a[a[t].left].right].size > a[a[t].right].size)
left_rotate(a[t].left),right_rotate(t);
else return;
}
else {
if (a[a[a[t].right].right].size > a[a[t].left].size)
left_rotate(t);
else if (a[a[a[t].right].left].size > a[a[t].left].size)
right_rotate(a[t].right),left_rotate(t);
else return;
}
maintain(a[t].left,0);
maintain(a[t].right,1);
maintain(t,0);
maintain(t,1);
}
void insert(int &t,int v) {
if (t == 0)
t = ++tot,a[t].Init(),a[t].key = v;
else {
a[t].size++;
if (v < a[t].key)
insert(a[t].left,v);
else insert(a[t].right,v);
maintain(t,v>=a[t].key);
}
}
int del(int &t,int v) {
if (!t) return 0;
a[t].size--;
if (v == a[t].key || v < a[t].key && !a[t].left
|| v > a[t].key && !a[t].right) {
if (a[t].left && a[t].right) {
int p = del(a[t].left,v+1);
a[t].key = a[p].key;
return p;
}
else {
int p = t;
t = a[t].left + a[t].right;
return p;
}
}
else return del(v<a[t].key?a[t].left:a[t].right,v);
}
int find(int t,int k) {
if (k <= a[a[t].left].size)
return find(a[t].left,k);
if (k > a[a[t].left].size + 1)
return find(a[t].right,k-a[a[t].left].size-1);
return a[t].key;
}
int main()
{
int i,j,k;
while (scanf("%d%d",&n,&m) != EOF) {
tot = root = 0;
char ope[10];
while (n--) {
scanf("%s",ope);
if (ope[0] == 'I') {
scanf("%d",&k);
insert(root,k);
}
else printf("%d\n",find(root,a[root].size+1-m));
}
}
}