Cod sursa(job #1482896)

Utilizator tamionvTamio Vesa Nakajima tamionv Data 8 septembrie 2015 11:52:22
Problema Avioane Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 2 kb
#include <fstream>
#include <iostream>
#include <deque>
#include <vector>
#include <cmath>
#include <algorithm>
using namespace std;

class my_deque{
	struct deque_element{
		int val, poz; };
	// val1 * (wp - poz1) < val2 * (wp - poz2)
	// wp (val2 - val1) > val2 * poz2 - val1 * poz1
	// wp = (val2 * poz2 - val1 * poz1) / (val2 - val1)
	int get_win_poz(const deque_element& a, const deque_element& b){
		const int val1 = a.val, val2 = b.val,
			poz1 = a.poz, poz2 = b.poz;
		if(val1 == val2){
			return a.poz; }
		return ceil(float(val2 * poz2 - val1 * poz1) /
			float(val2 - val1)); }
	deque<deque_element> dq;
	deque<int> win_poz;
public:
	my_deque(){}
	void print(){
		for(const auto x : dq){
			cout << "{" << x.val << ", " << x.poz << "} "; }
		cout << endl;
		for(const auto x : win_poz){
			cout << x << ' '; }
		cout << endl;
		cout << endl; }

	void push(const int val, const int poz){
		if(dq.size() == 0){
			dq.push_back({val, poz}); }
		else if(dq.size() == 1 && dq.back().val != val){
			dq.push_back({val, poz});
			win_poz.push_back(get_win_poz(dq[0], dq[1])); }
		else{
			deque_element tmp{val, poz};
			int this_win_poz = get_win_poz(dq.back(), tmp);
			while(!win_poz.empty() && win_poz.back() >= this_win_poz &&
					dq.back().val != val){
				dq.pop_back();
				win_poz.pop_back();
				this_win_poz = get_win_poz(dq.back(), tmp); }
			if(dq.back().val != val){
				win_poz.push_back(this_win_poz);
				dq.push_back(tmp); } } }
	void pop(const int poz){
		while(!win_poz.empty() && win_poz.front() <= poz){
			win_poz.pop_front();
			dq.pop_front(); } }
	int get_qty(const int poz){
		return (poz - dq.front().poz) * dq.front().val; } };

int main(){
	ifstream f("avioane.in");
	ofstream g("avioane.out");
	int n;
	f >> n;
	vector<int> v(n);
	for(auto& x : v){
		f >> x; }
	sort(begin(v), end(v));

	my_deque dq;
	dq.push(0, 0);
	int rez = 0;
	dq.print();
	for(int i = 0; i < n; ++i){
		dq.push(v[i], i+1);
		dq.pop(i+1);
		dq.print();
		rez = max(rez, dq.get_qty(i+1) + (n-i) * v[i]); }
	g << rez << '\n';
	return 0; }