스택은 마지막에서 첫 번째 출력 (LIFO)의 원칙을 기반으로 가장 기본적인 데이터 구조 중 하나입니다. 기본 조작은 푸시 (상단 위치에 소자를 삽입) 및 팝 (상단 요소를 삭제하는)을 포함한다. 스택의 모든 요소의 중간 값을 반환 - PeekMedian : 지금 당신은 여분의 작업과 스택을 구현하기로되어있다. 와 요소를, 중간 값이 정의된다 번째의 경우 가장 작은 소자 짝수 또는 번째의 경우, 홀수이다.
입력 사양 :
각 입력 파일은 하나의 테스트 케이스가 포함되어 있습니다. 각 경우에있어서, 첫 번째 라인은 양의 정수를 포함 . 그때 선은 각각 다음과 같은 3 형식 중 하나의 명령을 포함 따르
Push key
Pop
PeekMedian
여기서 key
양의 정수는 더 이상 없다
.
출력 사양 :
각각에 대해 Push
명령을 삽입 key
스택 출력 아무것도에. 각각 Pop
또는 PeekMedian
명령 라인에 대응하는 리턴 값을 출력한다. 명령이 무효 인 경우, 인쇄 Invalid
대신.
샘플 입력 :
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
문제의 의미
스택을 구현하기 위해, 스택의 출력 함수 값을 갖는다.
사고
펜윅 나무.
코드
#include <cstdio>
#include <cstring>
#include <stack>
using namespace std;
#define lowbit(i) ((i) & -(i)) // xxx100...
const int MAX_N = 100010;
stack<int> s;
int c[MAX_N]; // 树状数组
void update(int x, int v) { // 更新操作,将位置x的元素加上v
for (int i = x; i < MAX_N; i += lowbit(i))
c[i] += v; // 依次向上更新
}
int getSum(int x) { // 求和操作,返回位置1~x的元素之和
int sum = 0;
for (int i = x; i > 0; i -= lowbit(i))
sum += c[i];
return sum;
}
void peekMedia() { // 二分法求第K大
int l = 1, r = MAX_N, mid, k = (s.size() + 1) / 2;
while (l < r) {
mid = (l + r) / 2;
if (getSum(mid) >= k)
r = mid;
else
l = mid + 1;
}
printf("%d\n", l);
}
int main() {
int n, x;
char str[12];
scanf("%d", &n);
for (int i = 0; i < n; ++i) {
scanf("%s", str);
if (strcmp(str, "Push") == 0) {
scanf("%d", &x);
s.push(x); // 入栈
update(x, 1); // 将位置x加1
} else if (strcmp(str, "Pop") == 0) {
if (s.empty())
printf("Invalid\n");
else {
printf("%d\n", s.top());
update(s.top(), -1); // 将栈顶元素所在位置减1
s.pop(); // 出栈
}
} else if (strcmp(str, "PeekMedian") == 0) {
if (s.empty())
printf("Invalid\n");
else
peekMedia();
}
}
}