Luogu1801 黑匣子 堆

2022-07-02 16:36:17 字數 956 閱讀 5666

傳送門

題意:給出兩種命令:

add(x):把 x 元素放進 black box;

get:i 加 1,然後輸出 black box 中第 i 小的數。

輸出每次get操作的結果。

題解:注意到每次求的第k小中,k從1開始遞增。則維護乙個大根堆和乙個小根堆,大根堆裡記錄前k小的數字,小根堆裡記錄其他的數字。

這樣構造有乙個性質:

1.大根堆裡最大的數即為當前陣列中的第k小。

在遇到get操作之前,對於每個待加入的數字,判斷其是否為前k小,若是,則加入到大根堆中,並把大根堆中最大的數放到小根堆中;否則直接加入小根堆。

get操作:取出小根堆裡面最小的數即為答案,再將這個數取出加入到大根堆中,滿足上面的性質。

#include#include#include#includeusing namespace std;

const int maxn = 200005, maxm = 200005;

int a[maxn];

inline int read()

while(ch >= '0' && ch <= '9')

return k * f;

}priority_queue q1, q2;

//q1為小根堆,q2為大根堆

int main()

// for(int i = 1; i <= m; i++)

int now = 0, kth = 0, cur = 0;

for(int i = 1; i <= n; i++)

else

}else

}kth++;

int q1min = -q1.top(); q1.pop();

q2.push(q1min);

printf("%d\n", q1min); }

return 0;

}

洛谷P1801 黑匣子 堆

兩種操作 有點像對頂堆啊。每次維護乙個大根堆,保證只儲存最小的s ss個數字。其中s ss表示現在進行了s ss次get getge t操作。然後維護乙個小根堆,把其他所有數字儲存進去。這樣每次詢問完就可以把不在大根堆裡的最小的元素扔進大根堆裡。方便下一次詢問。時間複雜度o m log n o m ...

洛谷P1801 黑匣子 堆

兩種操作 有點像對頂堆啊。每次維護乙個大根堆,保證只儲存最小的s s個數字。其中s s表示現在進行了ss次g etge t操作。然後維護乙個小根堆,把其他所有數字儲存進去。這樣每次詢問完就可以把不在大根堆裡的最小的元素扔進大根堆裡。方便下一次詢問。時間複雜度o m log n o mlogn inc...

洛谷P1801 黑匣子

題目傳送門 分析 這題和另外乙個題目中位數非常相似,有興趣可以先看看,比這一題簡單。首先暴力模擬還是別想了,估計30 的資料都有點懸。正解應該是用二叉堆。但是如果用乙個堆當然不方便,所以建兩個堆,乙個大根堆,乙個小根堆,每次只要出現詢問操作,就把小根堆的堆頂丟進大根堆中維護,然後輸出就可以了,但是要...