1057. Stack (30)

题目:

Stack is one of the most fundamental data structures, which is based on the principle of Last In First Out (LIFO). The basic operations include Push (inserting an element onto the top position) and Pop (deleting the top element). Now you are supposed to implement a stack with an extra operation: PeekMedian -- return the median value of all the elements in the stack. With N elements, the median value is defined to be the (N/2)-th smallest element if N is even, or ((N+1)/2)-th if N is odd.

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive integer N (<= 105). Then N lines follow, each contains a command in one of the following 3 formats:

Push  key
Pop
PeekMedian

where key is a positive integer no more than 105.

Output Specification:

For each Push command, insert key into the stack and output nothing. For each Pop or PeekMedian command, print in a line the corresponding returned value. If the command is invalid, print "Invalid" instead.

Sample Input:
17
Pop
PeekMedian
Push 3
PeekMedian
Push 2
PeekMedian
Push 1
PeekMedian
Pop
Pop
Push 5
Push 4
PeekMedian
Pop
Pop
Pop
Pop
Sample Output:
Invalid
Invalid
3
2
2
1
2
4
4
5
3
Invalid
注意:
1、好吧,这道题目不用树状数组貌似还真解决不了。。。
2、关于树状数组大家可以尽量去查资料,具体的实现也不赘述了,但是要明白这里为什么要用到树状数组。要知道这里每次PeekMedian的时候都来个sort是肯定行不通的,那么现在就可以考虑另一个思路了,假如我有一个数组bit[](先不要在意为什么取名为bit这个细节),通过bit[i]可以计算出stack中<i的元素的个数(假设算法为f(bit[],i),那么我在PeekMedian的时候,只要知道这时stack中元素的个数n,那么我使用二分法就可以很快找到f(bit[],i)=n/2时的i的值了,而这就是我们要求的Median的值,这个思路就是把stack中的无序转换成bit中的有序,提高计算效率。而因为每次push和pop的时候都要改变bit[]中的相应元素,但是通过bit位运算可以很快做出这个改变,所以这个数组我就取名为bit[]了。
3、这里主要说明一下思路:
     1)建立一个stack(我习惯了用vector所以程序中没用到stack容器)、
     2)push和pop的时候,改变bit[]数组的相应项。
     3)PeekMedian的时候,使用二分法,找到记录个数=stack元素个数一半时的i的值时停止(注意这里的一半是指stack所有元素索引的中值,另外这个i一定是数值最小的那个i,因为可能有多个i都满足上述要求)

代码:
//1057 by Binary Index Tree
//see the following blog to understand Binary Index Tree
//http://blog.csdn.net/int64ago/article/details/7429868
#include<iostream>
#include<vector>
using namespace std;

#define max 100001
int bit[max];//binary index tree
vector<int>st;//the stack

int lowbit(int k)
{
	return k&(-k);
}

void add(int index,int value)
{//if a value is added or deleted in the stack, update the binary index tree
	while(index<max)
	{
		bit[index] += value;
		index += lowbit(index);
	}
}

int sum(int index)
{//calculate how many value which is smaller than index in the current stack
	int sum=0;
	while(index>0)
	{
		sum += bit[index];
		index -= lowbit(index);
	}
	return sum;
}

int binarysearch()
{//search the value of the median
	int pos=(st.size()+1)/2;//position of the median if stack is sorted
	int down=0,up=max-1;
	while(up>down)
	{
		int mid=(up+down)/2;
		if(sum(mid)>=pos)
			up=mid;
		else
			down=mid+1;
	}
	return down;
}

int main()
{
	int n;
	scanf("%d",&n);
	for(int i=0;i<n;++i)
	{
		char in[15];
		scanf("%s",in);
		if(in[1]=='u')
		{//Push
			int t;
			scanf("%d",&t);
			st.push_back(t);
			add(t,1);//update the binary index tree
		}
		else if(in[1]=='o')
		{//Pop
			if(st.empty())
				printf("Invalid\n");
			else
			{
				printf("%d\n",st[st.size()-1]);
				add(st[st.size()-1],-1);//update the binary index tree
				st.pop_back();
			}
		}
		else
		{//PeekMedian
			if(st.empty())
				printf("Invalid\n");
			else
			{
				int temp;
				temp=binarysearch();
				printf("%d\n",temp);
			}
		}
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值