#include <iostream>
#include <set>
#include <vector>
using
namespace
std;
struct
Pair {
int
value, index;
Pair(
int
v,
int
p)
: value(v)
, index(p)
{
}
bool
operator<(
const
Pair& o)
const
{
if
(index == o.index) {
return
false
;
}
else
if
(value == o.value) {
return
index < o.index;
}
else
{
return
value < o.value;
}
}
int
getValue()
const
{
return
value; }
void
renew(
int
v,
int
p)
{
value = v;
index = p;
}
friend
ostream& operator<<(ostream& os,
const
Pair& pair)
{
return
os <<
"("
<< pair.value <<
", "
<< pair.index
<<
")"
;
}
};
void
printMedian(multiset<Pair>& minSet,
multiset<Pair>& maxSet,
int
window)
{
if
(window % 2 == 0) {
auto
minSetLast = minSet.rbegin();
auto
maxSetFirst = maxSet.begin();
double
median = (minSetLast->getValue()
+ maxSetFirst->getValue())
/ 2.0;
cout << median <<
" "
;
}
else
{
if
(minSet.size() > maxSet.size()) {
auto
minSetLast = minSet.rbegin();
cout << minSetLast->getValue() <<
" "
;
}
else
{
auto
maxSetFirst = maxSet.begin();
cout << maxSetFirst->getValue() <<
" "
;
}
}
}
void
findMedian(
int
arr[],
int
n,
int
k)
{
multiset<Pair> minSet;
multiset<Pair> maxSet;
vector<Pair> windowPairs(
k, Pair(0, 0));
for
(
int
i = 0; i < k; i++) {
windowPairs[i].renew(arr[i], i);
}
for
(
int
i = 0; i < k / 2; i++) {
maxSet.insert(windowPairs[i]);
}
for
(
int
i = k / 2; i < k; i++) {
if
(arr[i] < maxSet.begin()->getValue()) {
minSet.insert(windowPairs[i]);
}
else
{
minSet.insert(*maxSet.begin());
maxSet.erase(maxSet.begin());
maxSet.insert(windowPairs[i]);
}
}
printMedian(minSet, maxSet, k);
for
(
int
i = k; i < n; i++) {
Pair& temp = windowPairs[i % k];
if
(temp.getValue()
<= minSet.rbegin()->getValue()) {
minSet.erase(minSet.find(temp));
temp.renew(arr[i], i);
if
(temp.getValue()
< maxSet.begin()->getValue()) {
minSet.insert(temp);
}
else
{
minSet.insert(*maxSet.begin());
maxSet.erase(maxSet.begin());
maxSet.insert(temp);
}
}
else
{
maxSet.erase(maxSet.find(temp));
temp.renew(arr[i], i);
if
(temp.getValue()
> minSet.rbegin()->getValue()) {
maxSet.insert(temp);
}
else
{
maxSet.insert(*minSet.rbegin());
minSet.erase(--minSet.end());
minSet.insert(temp);
}
}
printMedian(minSet, maxSet, k);
}
}
int
main()
{
int
arr[] = { 0, 9, 1, 8, 2, 7, 3, 6, 4, 5 };
int
k = 3;
int
n =
sizeof
(arr) /
sizeof
(arr[0]);
findMedian(arr, n, k);
return
0;
}