PAT甲级1057 Stack【树状数组】【二分】

题目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 } 

 

posted @ 2019-03-23 10:00  wyboooo  阅读(167)  评论(0编辑  收藏  举报