Given n operations, there are two types of operations: insert and query the k-largest number. N <= 1000000
Solution: Because this question has not been deleted, it becomes very simple. You only need to maintain a small top heap with a size of k.
However, if there is a delete operation, it becomes more complicated. So I wrote this question using SBT, and I wrote it twice in anger. I wrote it three more times tomorrow evening at half past ten, gold, there is nothing to say about the test template.
Test data:
8 3
I 1
I 2
I 3
Q
I 5
Q
I 4
Q
C producer code:
[Cpp]
# Include <stdio. h>
# Include <string. h>
# Deprecision 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 [t]. left]. left]. size> a [a [t]. right]. size)
Right_rotate (t );
Else if (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 [t]. right]. right]. size> a [a [t]. left]. size)
Left_rotate (t );
Else if (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", & 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 ));
}
}
}