【UOJ #280】【UTR #2】题目难度提升

时间:2023-03-10 00:31:39
【UOJ #280】【UTR #2】题目难度提升

http://uoj.ac/problem/280

非常难想的贪心,用set\(O(nlogn)\)。

调了一天qwq。

题解

【UOJ #280】【UTR #2】题目难度提升

#include<set>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = 100003; multiset <int> S;
multiset <int> ans;
multiset <int> :: iterator L;
multiset <int> :: iterator R; int a[N], n, hh, m; int main() {
scanf("%d", &n);
for (int i = 1; i <= n; ++i) {
scanf("%d", a + i); a[i] <<= 1;
S.insert(a[i]);
}
stable_sort(a + 1, a + n + 1);
int tmp;
for (tmp = (n + 1) / 2; tmp >= 1; --tmp)
if (a[tmp] == a[tmp + 1])
break; set <int> :: iterator h;
if (tmp == 0) {
S.erase(a[1]); ans.insert(a[1]); m = a[1];
printf("%d ", a[1] >> 1);
for (int i = 2; i <= n; ++i) {
L = S.begin();
h = ans.upper_bound(m);
if (h != ans.end() && (*h < *L || *h <= 2 * (*L) - m)) L = --S.end();
else L = --S.upper_bound(2 * (*L) - m);
printf("%d ", *L >> 1); ans.insert(*L);
if (!ans.count(m)) {
if (*L > m) m = *ans.upper_bound(m);
else m = *ans.lower_bound(m) - 1;
} else if (*L != m) {
if (*L > m) hh = *ans.upper_bound(m);
else hh = *--ans.lower_bound(m);
m = (1ll + m + hh) / 2;
}
S.erase(*L);
}
} else {
m = a[tmp];
S.erase(S.find(m)); S.erase(S.find(m));
ans.insert(m); ans.insert(m);
printf("%d %d ", m >> 1, m >> 1);
tmp = 2; bool flag = false;
while (S.size() > 1) {
L = --S.end();;
if (*L < m) {flag = true; break;}
ans.insert(*L); printf("%d ", *L >> 1);
S.erase(L);
L = S.upper_bound(m);
++tmp;
if (L == S.begin()) break;
--L;
ans.insert(*L); printf("%d ", *L >> 1);
S.erase(L);
++tmp;
} if (flag) {
while (S.size()) {
L = --S.end();;
printf("%d ", *L >> 1);
S.erase(L);
}
return 0;
} tmp = n - tmp;
for (int i = 1; i <= tmp; ++i) {
L = S.begin();
h = ans.upper_bound(m);
if (h != ans.end() && (*h < *L || *h <= 2 * (*L) - m)) L = --S.end();
else L = --S.upper_bound(2 * (*L) - m);
printf("%d ", *L >> 1); ans.insert(*L);
if (!ans.count(m)) {
if (*L > m) m = *ans.upper_bound(m);
else m = *ans.lower_bound(m) - 1;
} else if (*L != m) {
if (*L > m) hh = *ans.upper_bound(m);
else hh = *--ans.lower_bound(m);
m = (1ll + m + hh) / 2;
}
S.erase(L);
}
}
return 0;
}