Petya has recently learned data structure named "Binary heap".
The heap he is now operating with allows the following operations:
- put the given number into the heap;
- get the value of the minimum element in the heap;
- extract the minimum element from the heap;
Thus, at any moment of time the heap contains several integers (possibly none), some of them might be equal.
In order to better learn this data structure Petya took an empty heap and applied some operations above to it. Also, he carefully wrote down all the operations and their results to his event log, following the format:
- insert x — put the element with value x in the heap;
- getMin x — the value of the minimum element contained in the heap was equal to x;
- removeMin — the minimum element was extracted from the heap (only one instance, if there were many).
All the operations were correct, i.e. there was at least one element in the heap each time getMin or removeMin operations were applied.
While Petya was away for a lunch, his little brother Vova came to the room, took away some of the pages from Petya's log and used them to make paper boats.
Now Vova is worried, if he made Petya's sequence of operations inconsistent. For example, if one apply operations one-by-one in the order they are written in the event log, results of getMin operations might differ from the results recorded by Petya, and some of getMin or removeMin operations may be incorrect, as the heap is empty at the moment they are applied.
Now Vova wants to add some new operation records to the event log in order to make the resulting sequence of operations correct. That is, the result of each getMin operation is equal to the result in the record, and the heap is non-empty when getMin ad removeMin are applied. Vova wants to complete this as fast as possible, as the Petya may get back at any moment. He asks you to add the least possible number of operation records to the current log. Note that arbitrary number of operations may be added at the beginning, between any two other operations, or at the end of the log.
The first line of the input contains the only integer n (1 ≤ n ≤ 100 000) — the number of the records left in Petya's journal.
Each of the following n lines describe the records in the current log in the order they are applied. Format described in the statement is used. All numbers in the input are integers not exceeding 109 by their absolute value.
The first line of the output should contain a single integer m — the minimum possible number of records in the modified sequence of operations.
Next m lines should contain the corrected sequence of records following the format of the input (described in the statement), one per line and in the order they are applied. All the numbers in the output should be integers not exceeding 109 by their absolute value.
Note that the input sequence of operations must be the subsequence of the output sequence.
It's guaranteed that there exists the correct answer consisting of no more than 1 000 000 operations.
2 insert 3 getMin 4
4 insert 3 removeMin insert 4 getMin 4
4 insert 1 insert 1 removeMin getMin 2
6 insert 1 insert 1 removeMin removeMin insert 2 getMin 2
In the first sample, after number 3 is inserted into the heap, the minimum number is 3. To make the result of the first getMin equal to 4 one should firstly remove number 3 from the heap and then add number 4 into the heap.
In the second sample case number 1 is inserted two times, so should be similarly removed twice.
这道题的意思是说有这么个人,他有一天学了堆,他很开心,他就把堆的操作写在本子上。然后有一天他去吃早餐,回来却发现他弟弟把他的本子撕了几页做纸船,他欲哭无泪,让你来帮忙。
这道题要用到优先队列,对他的每一个操作进行分析得出结果即可。能不用cin,cout尽量不要用,容易超时
#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
struct node{
string s;
int num;
}a[1000010];
int main(){
int n,num;
string str;
while(~scanf("%d",&n)){
//cnt用来计算没毛病的操作和漏掉的操作总数
int cnt=0;
priority_queue<int, vector<int> ,greater<int> > que;
for(int i=0;i<n;i++){
cin>>str;
//当str为removeMin的时候是不需要输入数字的
if(str[0]!='r') scanf("%d",&num);
//如果是insert,就将输入的数字放进队列中
if(str[0]=='i') que.push(num);
else if(str[0]=='r'){
//当str为removeMin时如果队列为空的就说明
//少了insert操作,这个时候队列为空所以就可以随便放一个数字
if(que.empty()){
a[cnt].s="insert";
a[cnt++].num=666;
que.push(666);
}
//把队列里的最小值remove掉
que.pop();
}
else if(str[0]=='g'){
//当str为getMin且你的队列不为空时,
//如果队首比getMin后面的数字还要小,说明是少了removeMin操作
//因为先要将最小值remove掉才能getMinget到你的值为最小
while(!que.empty()&&que.top()<num){
a[cnt++].s="removeMin";
que.pop();
}
//队列为空时既然有getMin操作,说明肯定少了一个insert
//或者是队首比getMin后的值还要大,就说明操作中
//少了一个insert,insert的值就是getMin后的值
while(que.empty()||que.top()>num){
a[cnt].s="insert";
a[cnt++].num=num;
que.push(num);
}
}
//如果完美避开了以上的所有操作,
//就说明操作是没毛病的,存起来留着输出
a[cnt++].s=str;
//此时的操作如果不是removeMin(因为removeMin
//不用输入数字),那么输入的数字就是操作的数字
//上一行cnt++了,记得要减回去
if(str[0]!='r') a[cnt-1].num=num;
}
cout<<cnt<<endl;
//输出
for(int i=0;i<cnt;i++){
cout<<a[i].s;
if(a[i].s[0]!='r') printf(" %d",a[i].num);
putchar('\n');
}
}
}