Cod sursa(job #491715)

Utilizator perticas_catalinperticas catalin perticas_catalin Data 12 octombrie 2010 02:07:01
Problema Caramizi Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.77 kb
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>

using namespace std;

#define NM 200005
#define LM 1000005

int N, M, C[NM], Q[NM], LMAX;
long long SUM[NM], ANS[LM];

void read_and_process_data()
{
	scanf ("%d %d", &N, &M);
	
	for (int i = 1; i <= N; ++i) scanf ("%d", &C[i]);
	for (int i = 1; i <= M; ++i) 
	{
		scanf ("%d", &Q[i]);
		LMAX = max (LMAX, Q[i]);
	}	
		
	sort (C + 1, C + N + 1);
	
	/*
	for (int i = 1; i <= N; ++i) printf ("%d ", C[i]);
	printf ("\n");
	for (int i = 1; i <= M; ++i) printf ("%d ", Q[i]);
	*/
	
	//LMAX = Q[M - 1].first;
	
	for (int i = 1; i <= N; ++i) SUM[i] = SUM[i - 1] + C[i];
}

void solve0()
{
	// O(L * N)
	
	for (int l = 1; l <= LMAX; ++l)
	{
		long long tot = 0;
		
		for (int i = 1; i <= N; ++i) tot += min(C[i], l);
		
		long long ansc = tot/l;
		ansc *= l;
		ANS[l] = max(ANS[l - 1], ansc);
		
		//printf ("%d -> %d, ",l, ansc);
	}	
	
	//printf ("\n");
	
	for (int i = 1; i <= M; ++i) printf ("%lld\n", ANS[Q[i]]);
}

void solve1()
{
	// O(L * logN)
	
	for (int l = 1; l <= LMAX; ++l)
	{
		// caut primul indice mai mare sau egal cu l
		
		int st = 1, dr = N;
		
		while (st < dr)
		{
			int mij = (st + dr)/2;
			if (C[mij] < l) st = mij + 1;
			else dr = mij;
		}	
		
		int ind = st;
		if (C[ind] < l) ++ind;
		
		long long ansc = (SUM[ind - 1] + (long long)(N - ind + 1) * l)/l;
		ansc *= l;
		ANS[l] = max(ANS[l - 1], ansc);
		
		//printf ("%d -> %d, ",l, ansc);
	}
	
	//printf ("\n");
	
	for (int i = 1; i <= M; ++i) printf ("%lld\n", ANS[Q[i]]);	
	
}
int main()
{
	freopen ("caramizi.in", "r", stdin);
	freopen ("caramizi.out", "w", stdout);
	
	read_and_process_data();

	//solve0();	
	solve1();
	//solve2();

	
	
	return 0;
}