题目:https://pintia.cn/problem-sets/994805342720868352/problems/994805417945710592
题意:对一个栈进行push, pop和找中位数三种操作。
思路:
好久没写题。感觉傻逼题写多了稍微有点数据结构的都不会写了。
pop和push操作就不说了。
找中位数的话就二分去找某一个数前面一共有多少小于他的数,找到那个小于他的数刚好等于一半的。
找的过程中要用到前缀和,所以自然而然就应该上树状数组。
要注意树状数组的界应该是1e5而不是当前数的最大值。
1 //#include<bits/stdc++> 2 #include<stdio.h> 3 #include<iostream> 4 #include<algorithm> 5 #include<cstring> 6 #include<stdlib.h> 7 #include<queue> 8 #include<map> 9 #include<stack> 10 #include<set> 11 12 #define LL long long 13 #define ull unsigned long long 14 #define inf 0x7f7f7f7f 15 16 using namespace std; 17 const int maxn = 1e5 + 5; 18 int n, size; 19 int sum[maxn]; 20 stack<int>sss; 21 int small = 1, big = 1e5; 22 23 void add(int x, int val) 24 { 25 while(x < 1e5){ 26 sum[x] += val; 27 x += (x & -x); 28 } 29 } 30 31 int query(int x) 32 { 33 int ans = 0; 34 while(x){ 35 ans += sum[x]; 36 x -= (x & -x); 37 } 38 return ans; 39 } 40 41 int main() 42 { 43 scanf("%d", &n); 44 45 while(n--){ 46 string op; 47 cin>>op; 48 if(op == "Push"){ 49 int key; 50 cin>>key; 51 sss.push(key); 52 //small = min(small, key); 53 //big = max(big, key); 54 add(key, 1); 55 } 56 else if(op == "Pop"){ 57 if(sss.size() == 0){ 58 printf("Invalid\n"); 59 } 60 else{ 61 add(sss.top(), -1); 62 printf("%d\n", sss.top()); 63 sss.pop(); 64 } 65 } 66 else if(op == "PeekMedian"){ 67 if(sss.size() == 0){ 68 printf("Invalid\n"); 69 } 70 else{ 71 int st = small, ed = big; 72 int ans = 0; 73 while(st <= ed){ 74 int mid = (st + ed) / 2; 75 size = sss.size(); 76 int res = query(mid); 77 if(res < (size + 1) / 2){ 78 st = mid + 1; 79 } 80 else{ 81 ans = mid; 82 ed = mid - 1; 83 } 84 } 85 printf("%d\n", ans); 86 } 87 } 88 } 89 90 return 0; 91 }
原文地址:https://www.cnblogs.com/wyboooo/p/10582667.html
时间: 2024-11-08 02:16:12