Cod sursa(job #254616)

Utilizator vlad.maneaVlad Manea vlad.manea Data 7 februarie 2009 13:16:37
Problema Cuburi2 Scor 0
Compilator cpp Status done
Runda Stelele Informaticii 2009, clasele 9-10, ziua 2 Marime 1.69 kb
#include <stdio.h>
#define nmax (250005)

long long infinit, i;

long long turn[nmax];
long long sumad[nmax], sumas[nmax];

long long cd[nmax], cs[nmax];
long long N, M, left, left2, right, right2, leftThird, rightThird, final, valfinal, vx, vy, vz, fz;

long long evalu(long long mid, long long left, long long right)
{
	long long cdij, csij;

	cdij = cd[mid-1] - cd[left-1] - (mid-left)*sumad[left-1];
	csij = cs[mid+1] - cs[right+1] - (right-mid)*sumas[right+1];

	return cdij+csij;
}

int main()
{
	infinit = 8446744073709551610;

	freopen("cuburi2.in", "r", stdin);
	freopen("cuburi2.out", "w", stdout);

	scanf("%lld%lld", &N, &M);
	for (i = 1; i <= N; ++i)
		scanf("%lld", &turn[i]);

	for (i = 1; i <= N; ++i)
		sumad[i] = sumad[i-1] + turn[i];

	for (i = N; i >= 1; i--)
		sumas[i] = sumas[i+1] + turn[i];

	for (i = 1; i <= N; ++i)
		cd[i] = cd[i-1] + sumad[i];

	for (i = N; i >= 1; i--)
		cs[i] = cs[i+1] + sumas[i];

	while (M--)
	{
		scanf("%lld%lld", &left2, &right2);
		for (left = left2, right = right2, valfinal = infinit, final = i = 0; left <= right && i < 32; ++i )
		{
			leftThird = (2*left + right) / 3;
			rightThird = (left + 2*right) / 3;
			fz = (left + right) / 2;
			if ((vz = evalu(final, left2, right2)) < valfinal)
			{
				valfinal = vz;
				final = fz;
			}
			if ((vx = evalu(leftThird, left2, right2)) < valfinal)
			{
				valfinal = vx;
				final = leftThird;
			}
			if ((vy = evalu(rightThird, left2, right2)) < valfinal)
			{
				valfinal = vy;
				final = rightThird;
			}

			if (vx < vy)
				right = rightThird-1;
			else
				left = leftThird+1;
		}

		printf("%lld %lld\n", final, valfinal);
	}

	return 0;
}