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

http://uoj.ac/problem/280
非常难想的贪心,用set\(O(nlogn)\)
调了一天qwq。
题解

#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;
}
posted @ 2017-01-14 19:03  abclzr  阅读(347)  评论(0编辑  收藏  举报