当前位置:网站首页>PAT (Advanced Level) Practice 1057 Stack

PAT (Advanced Level) Practice 1057 Stack

2022-07-01 06:28:00 Keep--Silent

subject

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 NNN elements, the median value is defined to be the (N/2)(N/2)(N/2)-th smallest element if NNN is even, or ((N+1)/2)((N+1)/2)((N+1)/2)-th if NNN is odd.

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive integer NNN (≤105\le 10^5105). Then NNN 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 10510^5105.

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

   
    

General description

Three operations :

  • Insert x
  • Delete x
  • Query median

Their thinking

data size 1 0 5 10^5 105, So give up , So we need some specific structures , The complexity of the three operations that require a single insert and delete query must be less than n n n, So that the overall complexity does not exceed n 2 n^2 n2, So choose a tree array .

Insert and delete

const int Size = 1e5 + 10;
int vt[Size], n = Size - 5;;
int lb(int x) {
     return x & (-x); }
void update(int x,int size) {
    
    for (int i = x; i <= n; i+=lb(i)) {
    
        vt[i]+=size;
    }
}
  • Insert x: update(x,1);
  • Delete x: update(x,-1);

therefore :

  • Insert x
  • Delete x
  • Query median

Query median

The tree array represents the prefix and , We use it vt Storage quantity , Two points search that will do : That is, we are looking for the median , I.e. find The first position equal to or greater than half of the quantity .

int getsum(int index) {
    
    int cnt = 0;
    for (int i = index; i; i -= lb(i))cnt += vt[i];
    return cnt;
}
void Medeian() {
    
    int cnt = getsum(n);
    int pot = (cnt+1) / 2;
    if (cnt== 0) {
    
        printf("Invalid\n");
        return;
    }
    int l = 1, r = n;
    while (l < r) {
    
        int mid = l + r >> 1;
        if (getsum(mid) >= pot)r = mid;
        else l = mid + 1;
    }
    printf("%d\n",l);
}

thus

  • Insert x
  • Delete x
  • Query median

Complexity analysis

Dichotomous complexity log ⁡ n \log n logn,getsum Complexity log ⁡ n \log n logn, in total n n n operations , Overall complexity n log ⁡ 2 n n \log^2 n nlog2n

Complete code

#include <bits/stdc++.h>
using namespace std;

const int Size = 1e5 + 10;

int vt[Size], n = Size - 5;;
int lb(int x) {
     return x & (-x); }
void update(int x,int size) {
    
    for (int i = x; i <= n; i+=lb(i)) {
    
        vt[i]+=size;
    }
}
int getsum(int index) {
    
    int cnt = 0;
    for (int i = index; i; i -= lb(i))cnt += vt[i];
    return cnt;
}
void Medeian() {
    
    int cnt = getsum(n);
    int pot = (cnt+1) / 2;
    if (cnt== 0) {
    
        printf("Invalid\n");
        return;
    }
    int l = 1, r = n;
    while (l < r) {
    
        int mid = l + r >> 1;
        if (getsum(mid) >= pot)r = mid;
        else l = mid + 1;
    }
    printf("%d\n",l);
}

int  main() {
    
    stack<int>sk;
    int n,x;
    cin >> n;
    char ss[300];
    while (n--) {
    
        scanf("%s", &ss);
        if (ss[1] == 'o') {
    
            if (sk.size() == 0) {
    
                printf("Invalid\n");
                continue;
            }
            x = sk.top();  
            update(x, -1);
            sk.pop();
            printf("%d\n", x);
        }
        else  if (ss[1] == 'u') {
    
            scanf("%d", &x);
            sk.push(x);
            update(x, 1);
        }
        else {
    
            Medeian();
        }
    }
	return 0;
}
原网站

版权声明
本文为[Keep--Silent]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/182/202207010625279183.html