Cod sursa(job #258040)

Utilizator raduzerRadu Zernoveanu raduzer Data 14 februarie 2009 15:42:50
Problema Caramizi Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.35 kb
#include <cstdio>
#include <algorithm>
using namespace std;

const int MAX_N = 200010;
const int MAX_L = 1000010;

int n, m, z;
long long sum, s2;
int a[MAX_N];
long long sol[MAX_L];
long long prec[MAX_N];
long long car[MAX_N];

void solve(int x)
{
	int poz = lower_bound(prec + 1, prec + z + 1, x) - prec - 1;
	
	long long max = car[poz];
	if (max < sol[MAX_L - 10]) max = sol[MAX_L - 10];
	if (max < s2 - (s2 % x)) max = s2 - (s2 % x);
	
	printf("%lld\n", max);
}

int main()
{
	int i, x;
	freopen("caramizi.in", "r", stdin);
	freopen("caramizi.out", "w", stdout);
	
	scanf("%d %d", &n, &m);
	
	for (i = 1; i <= n; ++i)
	{
		scanf("%d", &a[i]);
		sum += a[i];
		s2 += a[i];
	}
	
	sort(a + 1, a + n + 1);
	
	int q = 0;
	long long s = 0;
	
	for (i = 1; i <= sum + 1 && i < MAX_L; ++i)
	{
		long long z = 0;
		
		while (a[q + 1] < i && q < n)
		{
			++q;
			s += a[q];
		}
		
		z = (long long)(n - q) * i + (long long)(s / i) * i;
		
		sol[i] = (sol[i - 1] > z) ? sol[i - 1] : z;
	}
	
	for (i = n; i; --i)
		if (s2 / (i + 1) + 1 <= s2 / i && s2 / i <= 2000000000 && s2 / i > MAX_L - 10)
		{
			prec[++z] = s2 / i;
			car[z] = (prec[z] * i > car[z - 1]) ? prec[z] * i : car[z - 1];
		}
	
	for (i = 1; i <= m; ++i)
	{
		scanf("%d", &x);
		if ( x <= MAX_L - 10) printf("%lld\n", sol[x]);
		else solve(x);
	}
}