Tsinghua OJ:隧道(Tunel)

隧道(Tunel)


Description

A tunnel is single and one-way. Each vehicle can only enter the tunnel at one end and exit it at the other end. Overtaking is not allowed. The tunnel has the limitation on the height of each vehicle. At any time, the administrator would like to know how high the highest vehicle is at this time.

Now you need to maintain the record of vehicles in and out with the query highest vehicle function.

Input

The 1st line contains only one integer, i.e., the number of the operation of both height query and vehicles in and out.

The following n lines indicate n operations in order. Each line is in one of the following formats.

1. E x	//One vehicle with the height of x enters the tunnel            //(x is an integer).
2. D		//One vehicle exits the tunnel.
3. M		//Query the height of the highest vehicle currently

Output

If the amount of D operation and M operation is m, output m lines. For each D operation, output the height of the vehicle that exits the tunnel. For each M operation, output all the queried maximum heights.

Example

Input

9
E 5
E 6
M
E 2
M
D
M
D
M

Output

6
6
5
6
6
2

Restrictions

0 <= n <= 2,000,000

0 <= x <= 231 - 1

Ensure that all vehicles in and out are legal.

Time: 2 sec

Memory: 256 MB

Hints

How to simulate a queue by multiple stacks. Please refer to the exercises in Chapter 4.

How to make a stack through which one can query the largest number?

How to make a queue through which one can query the largest number?

Please refer to the Note XA in Chapter 4 and Exercise 10-19, 10-20 in Exercise Analysis.

描述

现有一条单向单车道隧道,每一辆车从隧道的一端驶入,另一端驶出,不允许超车

该隧道对车辆的高度有一定限制,在任意时刻,管理员希望知道此时隧道中最高车辆的高度是多少

现在请你维护这条隧道的车辆进出记录,并支持查询最高车辆的功能

输入

第一行仅含一个整数,即高度查询和车辆出入操作的总次数n

以下n行,依次这n次操作。各行的格式为以下几种之一:

1. E x		//有一辆高度为x的车进入隧道(x为整数)
2. D		//有一辆车离开隧道
3. M		//查询此时隧道中车辆的最大高度

输出

若D和M操作共计m次,则输出m行

对于每次D操作,输出离开隧道车辆的高度

对于每次M操作,输出所查询到的最大高度

样例

见英文题面

限制

0 ≤ n ≤ 2,000,000

0 ≤ x ≤ 231 - 1

保证车辆的进出序列是合法的

时间:2 sec

空间:256 MB

提示

如何由多个栈来模拟一个队列?可参考第四章末尾的某习题。

如何实现一个能够高效获取最大值的栈?

如何实现一个可以高效获取最大值的队列?

可参考第04章XA节的讲义以及《习题解析》的[10-19]题、[10-20]题


代码如下:


#include <stdio.h>
//#include <stdlib.h>

const int SZ = 1 << 20;  //提升IO buff 
struct fastio{
	char inbuf[SZ];
	char outbuf[SZ];
	fastio(){
		setvbuf(stdin, inbuf, _IOFBF, SZ);
		setvbuf(stdout, outbuf, _IOFBF, SZ);
	}
}io;

#define N 2000001

int max(int x, int y)
{
	return x > y ? x : y;
}

class Stack
{
public:
	Stack();
	~Stack();
	bool empty();
	void push(int);
	int pop();
	int top();
private:
	int *stack;
	int loc;
	int capacity;
};

Stack::Stack()
{
	capacity = N;
	stack = new int[capacity];
	loc = 0;
}
Stack::~Stack()
{
	delete[] stack;
}
bool Stack::empty()
{
	if (0 == loc) return true;
	else return false;
}

void Stack::push(int value)
{
	stack[++loc] = value;
}

int Stack::pop()
{
	if (!empty()) return stack[loc--];
	else return -1;
}

int Stack::top()
{
	return stack[loc];
}

class SSqueue
{
public:
	SSqueue()
	{
		while (!s1.empty()) s1.pop();
		while (!s11.empty()) s11.pop();
		while (!s2.empty()) s2.pop();
		while (!s22.empty()) s22.pop();
	}
	void put(const int &e)
	{
		s22.push(max(e, s22.empty() ? e : s22.top()));
		s2.push(e);
	}

	int remove()
	{
		if (s1.empty())
		{
			while (!s2.empty())
			{
				int e = s2.top();
				s2.pop();
				s22.pop();
				s1.push(e);
				s11.push(max(e, s11.empty() ? e : s11.top()));
			}
		}
		int ret = s1.top();
		s1.pop();
		s11.pop();
		return ret;
	}
	int getMax()
	{
		if (s1.empty())
		{
			while (!s2.empty())
			{
				int e = s2.top();
				s2.pop();
				s22.pop();
				s1.push(e);
				s11.push(max(e, s11.empty() ? e : s11.top()));
			}
		}
		return max(s11.top(), s22.empty() ? 0 : s22.top());
	}
private:
	Stack s1, s11, s2, s22;
};

int main()
{
	int n;
	scanf("%d", &n);
	SSqueue ss;
	while (n--)
	{
		char c;
		while (scanf("%c", &c) && c != 'E' && c != 'D' && c != 'M');
		switch (c)
		{
		case 'E':
			int a;
			scanf("%d", &a);
			ss.put(a);
			break;
		case 'D':
			printf("%d\n", ss.remove());
			break;
		case 'M':
			printf("%d\n", ss.getMax());
			break;
		}
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值