Cod sursa(job #253974)

Utilizator anna_bozianuBozianu Ana anna_bozianu Data 6 februarie 2009 13:57:38
Problema Caramizi Scor 5
Compilator cpp Status done
Runda Stelele Informaticii 2009, clasele 9-10, ziua 1 Marime 2.1 kb
#include<stdio.h>
#define N 200010
int n,m,i,j,x,h,salt,c[N],cc[N],poz,ps,pd,
getst(int st,int dr),getdr(int st,int dr),getpoz(int st,int dr);
void readd(),sort(),calcmax(),calcmaxc(),hd(int ii,int nn),sw(int ii,int jj),getmax(int h),
solve();
long long L,sol,sol1,sol2,max[N],cmax[N];
int main()
{
	readd();
	sort();
	calcmax();
	calcmaxc();
	solve();
	return 0;
}
void readd()
{
	freopen("caramizi.in","r",stdin);
	freopen("caramizi.out","w",stdout);
	scanf("%d%d",&n,&m);
	for(i=1;i<=n;i++){scanf("%d",&c[i]);max[1]+=(long long)c[i];}
}
void sort()
{
	for(i=n/2;i>=1;i--)hd(i,n);
	for(i=n;i>=1;i--){sw(1,i);hd(1,i-1);}
}
void hd(int ii,int nn)
{
	int jj=ii<<1;
	if(jj>nn)return;
	if(jj<nn)if(c[jj+1]>c[jj])jj++;
	if(c[jj]>c[ii]){sw(ii,jj);hd(jj,nn);}
}
void sw(int ii,int jj)
{
	int aux=c[ii];c[ii]=c[jj];c[jj]=aux;
}
void calcmax()
{
	for(h=2;h<=n;h++)getmax(h);
}
void getmax(int h)
{   poz=n-h+1;
	for(i=1;i<=n;i++)cc[i]=c[i];
	while(cc[poz])
	{   salt=cc[poz]-cc[poz-1];
	    if(salt)
			{max[h]+=(long long)salt;for(j=poz;j<=n;j++)cc[j]-=salt;}
		else
		{	ps=getst(0,poz-1);
		    pd=getdr(poz,n+1);
			pd++;x=h;
			for(;pd<=n;){cc[pd++]--;x--;}
			for(;x;x--){cc[ps++]--;}
			max[h]++;
		}
	}
}
int getst(int st,int dr)
{   int mi;
	if(dr==st+1)return dr;
	mi=(dr+st)>>1;
	if(cc[mi]-cc[poz])return getst(mi,dr);
	return getst(st,mi);
}
int getdr(int st,int dr)
{   int mi;
	if(dr==st+1)return dr;
	mi=(st+dr)>>1;
	if(c[mi]-c[poz])return getdr(st,mi);
	return getdr(mi,dr);
}
void calcmaxc()
{   long long ii=1;
	for(i=1,ii=1;i<=n;i++,ii++)cmax[i]=ii*max[i];
	for(i=n-1;i>=1;i--)if(cmax[i]<cmax[i+1])cmax[i]=cmax[i+1];
}
void solve()
{
	for(;m;m--)
	{
		scanf("%lld",&L);
		if(L>=max[1]){ printf("%lld\n",cmax[1]);continue;}
		if(L<=max[n]){ sol=L*(long long)n;printf("%lld\n",sol);continue;}
		poz=getpoz(1,n);
		sol1=cmax[poz+1];
		sol2=L*(long long)poz;
		sol=(sol1>sol2)?sol1:sol2;
		printf("%lld\n",sol);
	}
}
int getpoz(int st,int dr)
{   int mi=(st+dr)>>1;
	if(dr==st+1)return st;
	if(max[i]>L)return getpoz(mi,dr);
	return getpoz(st,mi);
}