topic description
Given a non-negative integer sequence A i A_i of length N NAi, for all 1 ≤ k ≤ ( N + 1 ) / 2 1≤k≤(N+1)/21≤k≤(N+1 ) / 2 , exportA 1 A_1A1, A 1 ∼ A 3 A_1 \yes A_3A1∼A3, …, A 1 ∼ A 2 k − 1 A_1 \sim A_{2k - 1}A1∼A2k − 1 _median of . Namely the first 1 , 3 , 5 , … 1,3,5,…1,3,5,... the median of the numbers.
input format
1st 11 row is a positive integerNNN , represents the sequence length.
Second 22 rows containNNN non-negative integersA i ( A i ≤ 1 0 9 ) A_i (A_i ≤ 10^9)Ai(Ai≤109)。
output format
Total ( N + 1 ) / 2 (N + 1 ) / 2(N+1 ) / 2 lines,iiand rowsA1 , A 3 , … , A 2 k − 1 A_1, A_3, …, A_{2k - 1}A1,A3,…,A2k − 1 _median of .
Input and output samples
enter
7
1 3 5 7 9 11 6
output
1
3
5
6
Instructions/Tips
For 20 % 20\%20 % of data,N ≤ 100 N ≤ 100N≤100;
For 40 % 40\%4 0 % of data,N ≤ 3000 N ≤ 3000N≤3000;
For 100 % 100\%1 0 0 % of data,N ≤ 100000 N ≤ 100000N≤100000。
topic link
https://www.luogu.com.cn/problem/P1168
answer
data structure:
priority_queue<int, vector<int>, less<int> > pq;
train of thought
Suppose now there is a sorted array, as follows:
We can draw the following conclusions:
1. First, the left side of the median is smaller than the median;
2. Secondly, the right side of the median is greater than the median;
3. The left side of the median is arranged in order from large to small;
4. The right side of the median is arranged in order from small to large;
Then according to the principle of the heap, the top of the left heap stores the largest value to the left of the median, and the top of the right heap stores the smallest value to the right of the median, so that the median can be accurately located.
We construct two heaps, the left is the big root heap, and the right is the small root heap. Since the median is in the middle, we put it in the left big root heap, and of course it can also be placed in the right heap.
So how do we do it?
First, we read the first number into left leftl e ft queue, then this number is naturally the median, and it will be output .
Then, we read in two numbers each time, set x, yx, yx , y , for these two numbers, if it is less than the original median, that isleft.top ( ) left.top()l e f t . t o p ( ) , then wepush it pushpush 进 l e f t left l e f t inside, otherwise we push itpushpush 进 r i g h t right r i g h t inside. Why do you do this? becauseleft leftl e f t stores a number smaller than the median, so put the number smaller than the original median intoleft leftl e f t inside, likewise,left leftl e f t stores a number larger than the median, so put the number larger than the original median intoright rightr i g h t inside.
because we want to keep left leftThe elements in l e f t are better than right rightThere is one more r i g h t (because left leftleft 里比 r i g h t right There is an extra median in r i g h t ). So ifx , yx,yx,y are put intoleft leftleft 或 r i g h t right r i g h t inside. Then this requirement must be broken at this time, so we need to maintain the two queues, letleft leftThe elements in l e f t are better than right rightThere is one more in r i g h t .
Case 1: x , yx,yx,y 都 p u s h push push 进 l e f t left left
because itself left leftThe elements in l e f t are more than right rightThere are more elements in r i g h t than 1 11 个,本来是 l e f t . s i z e ( ) − 1 = = r i g h t . s i z e ( ) left.size()-1 == right.size() left.size()−1==right.size() ,然后变成了 l e f t . s i z e ( ) − 1 > r i g h t . s i z e ( ) left.size()-1 > right.size() left.size()−1>r i g h t . s i z e ( ) , for this case, specifyleft leftThe top element of the heap in l e f t is no longer the median, and the top of the heap is larger than the median, then we need toleft leftl e f t move the top element toright rightr i g h t inside.
Case 2: x , yx,yx,y 都 p u s h push push 进 r i g h t right right
because itself left leftThe elements in l e f t are more than right rightThere are more elements in r i g h t than 1 11 个,本来是 l e f t . s i z e ( ) − 1 = = r i g h t . s i z e ( ) left.size()-1 == right.size() left.size()−1==right.size() ,然后变成了 l e f t . s i z e ( ) = = r i g h t . s i z e ( ) − 1 left.size() == right.size()-1 left.size()==right.size()−1 , for this caseright rightThe top element in the r i g h t heap is the median, but in order to maintain the relationship between the two queue sizes, right rightr i g h t move the top element toleft leftl e ft inside .
code show as below:
#include <bits/stdc++.h>
using namespace std;
int main() {
int N;
cin >> N;
priority_queue<int, vector<int>, less<int> > left;
priority_queue<int, vector<int>, greater<int> > right;
int a;
cin >> a;
left.push(a);
cout << left.top() << endl;
int t = (N + 1) / 2 - 1;
while (t--) {
int x, y;
//每次读入两个数
cin >> x >> y;
//读入的数小于原来的中位数,则放入到右侧小顶堆
if (x <= left.top()) {
left.push(x);
} else {
right.push(x);
}
if (y <= left.top()) {
left.push(y);
} else {
right.push(y);
}
//如果左边堆的大小减一之后还比右堆大,说明此次操作把 x 和 y都push进了left堆,需要维护两个堆的大小关系
if (left.size() - 1 > right.size()) {
int temp = left.top();
left.pop();
right.push(temp);
}
//如果右边堆的大小比左堆大,说明此次操作把 x 和 y都push进了right堆,需要维护两个堆的大小关系
if (right.size() > left.size()) {
int temp = right.top();
right.pop();
left.push(temp);
}
cout << left.top() << endl;
}
return 0;
}