Cod sursa(job #253891)

Utilizator toni2007Pripoae Teodor Anton toni2007 Data 6 februarie 2009 13:24:09
Problema Caramizi Scor 60
Compilator cpp Status done
Runda Stelele Informaticii 2009, clasele 9-10, ziua 1 Marime 2.08 kb
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <map>
#include <set>

using namespace std;

const int maxN = 200100;
const int maxL = 2000000002;
const long long oo = 1LL << 60;

int V[maxN], Nr[maxN];
map<int,int> MyMap;
set<int> S;

long long Bmin[maxN], Sum[maxN];

int N, M;

bool posibil(int Hi, int Len){
	//fprintf(stderr, "%d %d\n", Hi, Len);
	set<int> :: iterator it;
	it = S.lower_bound(Len); 
	int pozMin;
	if (it == S.end())
		pozMin = N + 1;
	else
		pozMin = MyMap[*it];
	//fprintf(stderr, "%d %d\n", pozMin, *it);
	int nr = N - pozMin + 1, nrRamase, pozRamase;
	if (nr >= Hi)
		return true;
	nrRamase = N - nr;
	pozRamase = Hi - nr;
	//fprintf(stderr, "%d %d %d %d\n", nrRamase, pozRamase, nr, pozMin);
	if (pozRamase >= nrRamase)
		return false;
	if (1LL * Sum[nrRamase] >= 1LL * pozRamase * Len)
		return true;
	return false; 
}
int calc(int x){
	int l, r, mid;
	
	l = 1; r = maxL;
	
	while (l < r){
		mid = (l + r + 1) >> 1;
		//fprintf(stdout, "%d %d\n", l, r);
		if (posibil(x, mid))
			l = mid ;
		else
			r = mid - 1;
	}
	
	return l;
}

int search(int x){
	int l, r, mid;
	l = 1; r = N;
	
	while (l < r){
		mid = (l + r) >> 1;
		if (Nr[mid] <= x)
			r = mid;
		else
			l = mid + 1;
	}
	
	while (l <= N && Nr[l] >= x) ++l;
	return l;
}
int main(){
	int i, a, poz;
	long long Sol;
	
	freopen("caramizi.in", "r", stdin);
	freopen("caramizi.out", "w", stdout);
	
	scanf("%d%d", &N, &M);
	
	for (i = 1; i <= N; ++i)
		scanf("%d", &V[i]);
	
	sort(V + 1, V + N + 1);
	
	for (i = 1; i <= N; ++i){
		Sum[i] = Sum[i - 1] + V[i];	
	}
	
	for (i = N; i; --i){
		MyMap[V[i]] = i;
		S.insert(V[i]);
	}
	
	
	for (i = 1; i <= N; ++i)
		Nr[i] = calc(i);
	
	//for (i = 1; i <= N; ++i)
		//printf("%d ", Nr[i]);
		
	for (i = N; i; --i)
		Bmin[i] = max(Bmin[i + 1], 1LL * Nr[i] * i);
	
	//for (i = 1; i <= N; ++i)
		//printf("%lld ", Bmin[i]);
	for (i = 1; i <= M; ++i){
		scanf("%d", &a);
		poz = search(a);
		Sol = max(1LL * (poz - 1) * a, Bmin[poz]);
		//printf("%d %lld\n", poz, Sol);
		printf("%lld\n", Sol);
	}
	//fprintf(stderr, "%d %d %d\n", search(10), search(15), search(7));
}