Cod sursa(job #465808)

Utilizator darrenRares Buhai darren Data 25 iunie 2010 13:17:05
Problema Minim2 Scor 0
Compilator cpp Status done
Runda Stelele Informaticii 2010, gimnaziu si clasa a IX-a, Ziua 1 Marime 1.85 kb
#include<fstream>
#include<algorithm>
using namespace std;

const double eps = 0.0000001;

int n, sh, step, hpos[100001];
double heap[100001], act[100001], powb[10001], a, b, r, sum;
bool ok[100001];

void push(double v, int p)
{
	heap[++sh] = v;
	hpos[sh] = p;
	
	int son = sh, fat = sh / 2;
	while (fat != 0)
	{
		if (heap[fat] < heap[son])
		{
			swap(heap[fat], heap[son]);
			swap(hpos[fat], hpos[son]);
			
			fat /= 2;
			son /= 2;
		}
		else
			break;
	}
}

void update()
{
	int fat = 1, son = 2;
	while (son <= sh)
	{
		if (son < sh && heap[son] < heap[son + 1])
			++son;
		if (heap[fat] < heap[son])
		{
			swap(heap[fat], heap[son]);
			swap(hpos[fat], hpos[son]);
			
			fat = son;
			son *= 2;
		}
		else
			break;
	}
}

int main()
{
	ifstream fin("minim2.in");
	ofstream fout("minim2.out");
	fin >> n;
	
	for (int i = 1; i <= n; ++i)
	{
		fin >> act[i];
		sum += act[i];
	}
	fin >> a >> b >> r;
	for (int i = 1; i <= n; ++i)
	{
		push(act[i] - act[i] * a, i);
	}
	
	powb[0] = 1;
	for (int i = 1; i <= 10000; ++i)
		powb[i] = powb[i - 1] * b;
	
	double maxs;
	while (sum > r - eps)
	{
		if (!ok[hpos[1]])
		{
			sum -= heap[1];
			act[hpos[1]] *= a;
			heap[1] = act[hpos[1]] - act[hpos[1]] * b;
			ok[hpos[1]] = true;
			
			++step;
		}
		else
		{
			//Mai trebuie lucrat
			/*
			sum -= heap[1];
			act[hpos[1]] *= b;
			heap[1] = act[hpos[1]] - act[hpos[1]] * b;
			*/
			if (sh > 1) maxs = heap[2];
			if (sh > 2 && heap[3] > maxs) maxs = heap[3];
			
			int stp, i;
			for (stp = 1; stp << 1 <= 10000; stp <<= 1);
			for (i = 0; stp; stp >>= 1)
				if (i + stp <= 10000)
					if (act[hpos[1]] * powb[i + stp - 1] - act[hpos[1]] * powb[i + stp] > maxs)
						i += stp;
					
			sum -= act[hpos[1]] - act[hpos[1]] * powb[i];
			act[hpos[1]] *= powb[i];
			heap[1] = act[hpos[1]] - act[hpos[1]] * b;
			step += i;
		}
		
		update();
	}
	
	fout << step;
}