Cod sursa(job #252481)

Utilizator eferLiviu Ciortea efer Data 4 februarie 2009 15:06:29
Problema Caramizi Scor Ascuns
Compilator cpp Status done
Runda Marime 1.73 kb
#include <cstdio>
#include <cassert>
#include <algorithm>
using namespace std;

const int MAX_N = 200001;
const int MAX_M = 200001;
const int MAX_H = 1000001;
const int MAX_L = 2000000001;

typedef long long LL;

int N, M, C[MAX_N], L[MAX_M];
LL bst[MAX_H], res[MAX_M];

void read_data() {
	FILE* fin = fopen("caramizi.in", "rt");
	fscanf(fin, "%d %d", &N, &M);

	assert(1 <= N && N < MAX_N);
	assert(1 <= M && M < MAX_M);

	for (int i = 0; i < N; ++i) {
		fscanf(fin, "%d", &C[i]);
		assert(1 <= C[i] && C[i] < MAX_H);
	}
	for (int i = 0; i < M; ++i) {
		fscanf(fin, "%d", &L[i]);
		assert(1 <= L[i] && L[i] < MAX_L);
	}

	fclose(fin);
}

void solve() {
	sort(C, C+N);

	LL sum = 0;
	int idx = 0, n = 1;
	for (; n < MAX_H; ++n) {
		bst[n] = (LL)n * (sum/n + (N - idx));
		bst[n] = max(bst[n-1], bst[n]);

		while (idx < N && C[idx] == n) {
			sum += C[idx++];
		}
	}

	//n--, idx = 1;
	//max_L[0] = n;
	//bst_after[0] = bst[n];
	//for (int h = sum / n; h > 0; --h, idx++) {
	//	if (sum / MAX_L > h) break;
	//	max_L[idx] = sum / h;
	//	bst_after[idx] = max_L[idx] * h;
	//	bst_after[idx] = max(bst_after[idx], bst_after[idx-1]);
	//}

	for (int i = 0; i < M; ++i) {
		res[i] = bst[L[i]];
		//if (L[i] <= n) res[i] = bst[L[i]];
		//else {
		//	if (L[i] > sum) L[i] = sum;
		//	int p = lower_bound(max_L, max_L+idx, L[i] + 1) - max_L;
		//	if (p == idx) p--;
		//	int h = sum / max_L[p];
		//	LL now = (LL)h * L[i];
		//	res[i] = max(bst_after[p-1], now);
		//}
	}
}

void write_results() {
	FILE* fout = fopen("caramizi.out", "wt");
	for (int i = 0; i < M; ++i) {
		fprintf(fout, "%lld\n", res[i]);
	}
	fclose(fout);
}

int main() {
	read_data();
	solve();
	write_results();

	return 0;
}