Cod sursa(job #2626764)

Utilizator MarcGrecMarc Grec MarcGrec Data 8 iunie 2020 11:31:02
Problema Avioane Scor 70
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.03 kb
#define MAX_N 100000
 
#include <fstream>
#include <algorithm>
#include <cstdint>
using namespace std;
 
ifstream fin("avioane.in");
ofstream fout("avioane.out");
 
int n, B[MAX_N + 1];
 
int l, r, DP[MAX_N + 1];
 
int step;
 
int ProfitFunc(int left, int right);
int StepProfit(int index);
int OutrunStep(int left, int right);
 
void Insert();
 
int main()
{
	fin >> n;
	
	for (int i = 1; i <= n; ++i)
	{
		fin >> B[i];
	}
	
	sort(B + 1, B + 1 + n);
	
	int profit = 0;
	
	l = r = DP[1] = 1;
	for (step = 2; step <= n; ++step)
	{
		while ((step <= n) && (B[step] == B[step - 1]))
		{
			++step;
		}
		
		if (step > n)
		{
			break;
		}
		
		while (((l + 1) <= r) && (OutrunStep(DP[l], DP[l + 1]) <= step))
		{
			++l;
		}
		
		{
			int aux = ProfitFunc(DP[l], step);
			if (profit < aux)
			{
				profit = aux;
			}
		}
		
		Insert();
	}
	
	fout << profit;
	
	fin.close();
	fout.close();
	return 0;
}
 
int ProfitFunc(int left, int right)
{
	return (B[left] * (right - left)) + (B[right] * (n - right + 1));
}
 
int StepProfit(int index)
{
	return B[index] * (step - index + 1);
}
 
int OutrunStep(int left, int right)
{
	int vel = B[right] - B[left];
	
	if (vel == 0)
	{
		return -1;
	}
	
	int dist = B[left] * (right - left + 1) - B[right];
	
	if (dist <= 0)
	{
		return 0;
	}
	
	int aux = dist / vel;
	
	if ((dist % vel) != 0)
	{
		++aux;
	}
	
	return aux + right;
}
 
void Insert()
{
	if (StepProfit(DP[l]) < StepProfit(step))
	{
		DP[l] = step;
		r     = l;
		
		return;
	}
	
	int left = l + 1, right = r, mid;
	
	int pos = -1;
	while (left <= right)
	{
		mid = (left + right) / 2;
		
		int res = OutrunStep(DP[mid - 1], step);
		
		if (res == -1)
		{
			left = mid + 1;
		}
		else
		{
			if (res <= OutrunStep(DP[mid - 1], DP[mid]))
			{
				pos   = mid;
				right = mid - 1;
			}
			else
			{
				left = mid + 1;
			}
		}
	}
	
	if (pos == -1)
	{
		DP[++r] = step;
	}
	else
	{
		DP[pos] = step;
		r       = pos;
	}
}