PAT (고급 레벨) 연습 1057 스택 (30 점) 펜윅 나무]

스택은 마지막에서 첫 번째 출력 (LIFO)의 원칙을 기반으로 가장 기본적인 데이터 구조 중 하나입니다. 기본 조작은 푸시 (상단 위치에 소자를 삽입) 및 팝 (상단 요소를 삭제하는)을 포함한다. 스택의 모든 요소의 중간 값을 반환 - PeekMedian : 지금 당신은 여분의 작업과 스택을 구현하기로되어있다. N 요소를, 중간 값이 정의된다 ( N / 2 ) (N / 2) 번째의 경우 가장 작은 소자 N 짝수 또는 ( ( N + 1 ) / 2 ) ((N + 1) / 2) 번째의 경우, N 홀수이다.

입력 사양 :

각 입력 파일은 하나의 테스트 케이스가 포함되어 있습니다. 각 경우에있어서, 첫 번째 라인은 양의 정수를 포함 N ( 1 0 5 ) N (≤10 ^ 5) . 그때 N 선은 각각 다음과 같은 3 형식 중 하나의 명령을 포함 따르

Push key
Pop
PeekMedian

여기서 key양의 정수는 더 이상 없다 1 0 5 10 ^ 5 .

출력 사양 :

각각에 대해 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();
        }
    }
}
发布了184 篇原创文章 · 获赞 19 · 访问量 2万+

추천

출처blog.csdn.net/Exupery_/article/details/104158745