PAT: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.

 

輸入描述:

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.


 

輸出描述:

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.

 

輸入例子:

17
Pop
PeekMedian
Push 3
PeekMedian
Push 2
PeekMedian
Push 1
PeekMedian
Pop
Pop
Push 5
Push 4
PeekMedian
Pop
Pop
Pop
Pop

 

輸出例子:

Invalid
Invalid
3
2
2
1
2
4
4
5
3
Invalid

【解析】

最近老遇到樹狀數組,不得不說很有用了吧。

題意:就是棧的操作,push就推入棧中不用輸出,pop就彈出棧頂元素並輸出,還有一種peekmedian操作,找到第(n+1)/2【題目是說偶數n/2,奇數(n+1)/2但是其實取整一下都是(n+1)/2不難理解吧】小的數並輸出。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 100010;
using namespace std;
stack<int> s;//棧只用來操作pop和push
int c[maxn];//c纔是用來peekmedian的
int lowbit(int x)
{
	return x & (-x);
}
void update(int x, int v)
{
	for (int i = x; i < maxn; i += lowbit(i))
		c[i] += v;
}
int getsum(int x) 
{
	int sum = 0;
	for (int i = x; i >= 1; i -= lowbit(i))
		sum += c[i];
	return sum;
}
void PeekMedian() 
{
	int left = 1, right = maxn, mid, k = (s.size() + 1) / 2;
	while (left < right) 
	{
		mid = (left + right) / 2;
		if (getsum(mid) >= k)
			right = mid;
		else
			left = mid + 1;
	}
	printf("%d\n", left);
}
int main() 
{
	int n, temp;
	scanf("%d", &n);
	char str[20];
	while(n--)
	{
		scanf("%s", str);
		if (str[1] == 'u') 
		{
			scanf("%d", &temp);
			s.push(temp);
			update(temp, 1);//push就是+1
		}
		else if (str[1] == 'o')
		{
			if (!s.empty()) 
			{
				update(s.top(), -1);//刪除就是-1
				printf("%d\n", s.top());
				s.pop();
			}
			else 
				printf("Invalid\n");
		}
		else 
		{
			if (!s.empty())
				PeekMedian();
			else
				printf("Invalid\n");
		}
	}
	return 0;
}

 

 

發佈了89 篇原創文章 · 獲贊 11 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章