Submission #198456

#TimeUsernameProblemLanguageResultExecution timeMemory
198456QCFiumHoliday (IOI14_holiday)C++14
24 / 100
5077 ms5752 KiB
#include <bits/stdc++.h>

int ri() {
	int n;
	scanf("%d", &n);
	return n;
}

std::vector<int> a;
int start, d;

struct TopK {
	int k;
	std::multiset<int> upper;
	std::multiset<int> lower;
	int64_t upper_sum = 0;
	TopK (int k) : k(k) {}
	void low_to_up() {
		assert(lower.size());
		auto greatest = std::prev(lower.end());
		upper.insert(*greatest);
		upper_sum += *greatest;
		lower.erase(greatest);
	}
	void up_to_low() {
		assert(upper.size());
		auto lowest = upper.begin();
		upper_sum -= *lowest;
		lower.insert(*lowest);
		upper.erase(lowest);
	}
	void insert(int n) {
		if (!k) {
			lower.insert(n);
			return;
		}
		if ((int) upper.size() == k) {
			auto lowest = upper.begin();
			if (*lowest < n) {
				lower.insert(*lowest);
				upper_sum -= *lowest;
				upper_sum += n;
				upper.erase(lowest);
				upper.insert(n);
			} else lower.insert(n);
		} else upper.insert(n), upper_sum += n;
	}
	void erase(int n) {
		if (upper.size() && *upper.begin() <= n) {
			assert(upper.count(n));
			upper_sum -= n;
			upper.erase(upper.find(n));
			if (lower.size()) low_to_up();
		} else assert(lower.count(n)), lower.erase(lower.find(n));
	}
	void set_k(int new_k) {
		for (; k < new_k; k++) {
			while (lower.size() && (int) upper.size() <= k) low_to_up();
		}
		for (; k > new_k; k--) {
			while ((int) upper.size() >= k) up_to_low();
		}
		k = new_k;
	}
};
struct RangeSum {
	TopK topk;
	int l = 0;
	int r = 0;
	bool invert = false;
	RangeSum () : topk(d) {}
	void set_lr(int new_l, int new_r) {
		new_r++;
		if (l == r) l = r = new_l;
		while (l > new_l) topk.insert(a[--l]);
		while (r < new_r) topk.insert(a[r++]);
		while (l < new_l) topk.erase(a[l++]);
		while (r > new_r) topk.erase(a[--r]);
		new_r--;
		int move;
		if (!invert) {
			move = new_r - start;
			if (new_l < start) move += new_r - new_l;
		} else {
			move = start - new_l;
			if (new_r > start) move += new_r - new_l;
		}
		topk.set_k(std::max(0, d - move));
	}
	int64_t sum() { return topk.upper_sum; }
};

/*
std::vector<int64_t> dp;
void monotone_minima1(int rl, int rr, int ll, int lr) {
	
}*/

long long int findMaxAttraction(int n, int start_, int d_, int attraction[]) {
	a.resize(n);
	for (int i = 0; i < n; i++) a[i] = attraction[i];
	start = start_;
	d = d_;
	
	RangeSum sum;
	int64_t res = 0;
	for (int i = 0; i <= start; i++) {
		for (int j = start; j < n; j++) {
			sum.set_lr(i, j);
			res = std::max(res, sum.sum());
		}
	}
	sum.invert = true;
	for (int i = 0; i <= start; i++) {
		for (int j = start; j < n; j++) {
			sum.set_lr(i, j);
			res = std::max(res, sum.sum());
		}
	}
	
	/*
	start--;
	// go right first
	dp.assign(n + 1, 0);
	monotone_minima1(start + 1, n, 0, j*/
	return res;
}

/*
int main() {
	int n = ri();
	int start = ri();
	int d = ri();
	int a[n];
	for (auto &i : a) i = ri();
	std::cout << findMaxAttraction(n, start, d, a) << std::endl;
	
	return 0;
}
//*/

Compilation message (stderr)

holiday.cpp: In function 'int ri()':
holiday.cpp:5:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  scanf("%d", &n);
  ~~~~~^~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...