Cod sursa(job #256017)

Utilizator andrei-alphaAndrei-Bogdan Antonescu andrei-alpha Data 10 februarie 2009 23:13:20
Problema Cuburi2 Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.7 kb
using namespace std;

#include <bitset>
#define f first
#define s second
#define II inline
#define ll long long
#define FOR(i,a,b) for(int i=a;i<=b;++i)
#define FOL(i,a,b) for(int i=a;i>=b;--i)
#define mp make_pair
#define IN  "cuburi2.in"
#define OUT "cuburi2.out"
#define N_MAX 1<<18

int N,M,x,y;
int V[N_MAX];
ll L[N_MAX],R[N_MAX],S[N_MAX],SR[N_MAX],SL[N_MAX];

II void scan()
{
	freopen(IN,"r",stdin);
	freopen(OUT,"w",stdout);
	scanf("%d%d\n",&N,&M);
	
	FOR(i,1,N)
		scanf("%d",V+i);
}

II ll suma(int poz)
{
	return S[poz] - L[x-1] - SL[x-1] * (ll)(poz-x) - R[y+1] - SR[y+1] * (ll)(y-poz);
}

II pair<ll,ll> find()
{
	int aa,bb,a = x,b = y;
	
	for(;a+2<b;)
	{
		aa = a + (b-a) / 3;
		bb = b - (b-a) / 3;
		
		ll s1(suma(a)),s2(suma(aa)),s3(suma(bb)),s4(suma(b));
		
		if(s1 > s2 && s2 > s3 && s3 > s4)
			a = bb;
		if(s1 < s2 && s2 < s3 && s3 < s4)
			b = aa;
		if(s1 > s2 && s2 > s3 && s3 < s4)
			a = aa;
		if(s1 > s2 && s2 < s3 && s3 < s4)
			b = bb;
	}
	
	pair<ll,ll> rez;
	if(suma(a) < suma(a+1) )
		rez = mp(a,suma(a));
	else
		if(suma(a+1) < suma(b))
			rez = mp(a+1,suma(a+1));
		else
			rez = mp(b,suma(b));
	return rez;	
}

II void compute()
{
	FOL(i,N,1)
		SR[i] = SR[i+1] + V[i];
	FOR(i,1,N)
		SL[i] = SL[i-1] + V[i];
	
	ll sum(0);
	FOR(i,2,N)
		sum += (ll)V[i] * (i-1);
	
	FOR(i,1,N)
	{
		S[i] = sum;
		sum += SL[i];
		sum -= SR[i+1];
	}	
	FOR(i,1,N)
		L[i] = L[i-1] + SL[i];
	FOL(i,N,1)
		R[i] = R[i+1] + SR[i];
}

II void solve()
{
	FOR(i,1,M)
	{
		scanf("%d%d\n",&x,&y);
		pair<ll,ll> rez = find();
		printf("%lld ",rez.f);
		printf("%lld\n",rez.s);
	}
}

int main()
{
	scan();
	compute();
	solve();
	return 0;
}