TIOJ-1168

進階的入門

https://tioj.ck.tp.edu.tw/problems/1168

Description

你需要實作五個函式:

1
2
3
4
5
void pop_big();
void pop_small();
void push(int s);
int big();
int small();

其中第一個函式需要將最大的數字移除,第二個函式需要將最小的數字移除,第三個函式需要將一個數加入目前的數字們,第四個函式需要回傳當前的最大值,第五個函式需要回傳當前的最小值。
假設一開始沒有任何數字,請你實作這五個操作。

保證當沒有數字的時候只會呼叫 push ,並且加入的數字 $\leq 10^9$ ,五個函數的總呼叫次數 $\leq 10^6$ 。

Solution

好久之前就一直卡這題總算AC了@_@

最直覺的想法就是開一個multiset或map,但這題的時限超誇張的緊
可以想到利用 priority_queue 維護最大最小
然而假如一個數字在最大堆被pop掉,不容易在最小堆裡面把他給刪除

我一開始的想法是開 unordered_map 之類的紀錄每個數字的個數,想當然而吃了TLE
後來查了解才發現紀錄插入編號並且維護編號幾的被 pop 了就可以
於是我就在 priority_queue 裡面存編號,並且自己寫compare函式
不過這樣寫的locality很差,似乎會讓常數暴增

改成用struct包住之後剩下最後兩筆TLE,試了好久之後才想到 priority_queue 是用 vector 實作,動態開的空間顯然會浪費很多常數,不如自己靜態開一個大陣列
注意到 pop 操作最多就是呼叫次數的一半,所以 heap 只要開 5e5 就好了, push 的時候多出去的可以直接丟掉
至於 popped 陣列應該還是要開到 1e6 ,因為被 pop 的東西有可能編號很大,TIOJ上的測資似乎沒考慮到這個地方所以開 5e5 也能AC

AC code

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#pragma g++ optimize("Ofast")
#pragma loop_opt(on)
#include "lib1168.h"
#define ff first
#define ss second

const int N = 500001;

struct node {
    int val, id;
    bool operator<(const node &b)const{return val<b.val;}
};
struct heap {
    node v[N];
    int sz;
    void push(node x) {
        v[sz++] = x;
        std::push_heap(v,v+sz);
        if(sz >= N) sz = N-1;
    }
    node top() {return v[0];}
    void pop() {
        std::pop_heap(v,v+sz);
        --sz;
    }
} mx, mn;
int tot;
bool popped[N]; // should be N*2?
inline void push(int x) {
    mx.push({x, tot});
    mn.push({-x, tot});
    ++tot;
}
inline int big() {
    while(popped[mx.top().id]) mx.pop();
    return mx.top().val;
}
inline int small() {
    while(popped[mn.top().id]) mn.pop();
    return -mn.top().val;
}
inline void pop_big() {
    while(popped[mx.top().id]) mx.pop();
    popped[mx.top().id] = 1;
    mx.pop();
}
inline void pop_small() {
    while(popped[mn.top().id]) mn.pop();
    popped[mn.top().id] = 1;
    mn.pop();
}
comments powered by Disqus