Cod sursa(job #1558847)

Utilizator borcanirobertBorcani Robert borcanirobert Data 29 decembrie 2015 17:38:43
Problema Cuburi2 Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.01 kb
#include <cstdio>
#include <iostream>
using namespace std;

FILE *f = fopen( "cuburi2.in", "r" );
FILE *g=  fopen( "cuburi2.out", "w" );

const int MAX = 250010;
const long long INF = 9999999999999999;
long long H[MAX];
long long l[MAX], r[MAX];
long long ns[MAX], nd[MAX];
long long N, M;
long long x, y;
long long p;
char s[MAX];
int P = MAX - 1;

void BinarySearch( int x, int y );
void Next();
void Get( long long& x );

int main()
{
	int i;
	
	Get(N);
	Get(M);
	for ( i = 1; i <= N; i++ )
	{
		Get(x);
		H[i] = x;
	}
	
	l[1] = 0;
	for ( i = 2; i <= N; i++ )
	{
		p += H[i - 1];
		l[i] = l[i - 1] + p;
		ns[i] = p;
	}
	
	r[N] = 0; p = 0;
	for ( i = N - 1; i >= 1; i-- )
	{
		p += H[i + 1];
		r[i] = r[i + 1] + p;
		nd[i] = p;
	}
	
	/*for ( i = 1; i <= N; i++ )
		fout << l[i] << ' ';
	fout << '\n';
	for ( i = 1; i <= N; i++ )
		fout << r[i] << ' ';
	fout << '\n';	*/
	
	for ( i = 1; i <= M; i++ )
	{
		Get(x); Get(y);
		BinarySearch(x, y);
	}
	
	fclose(f);
	fclose(g);
	return 0;
}

void BinarySearch( int x, int y )
{
	long long sl = ns[x], sr = nd[y];
	long long i1 = x, i2 = y;
	long long st = x, dr = y, mid, poz = x;
	long long s1, s2;
	
	while ( st <= dr )
	{
		mid = ( st + dr ) / 2;
		
		if ( l[mid] - ( sl * ( mid - i1 ) + l[x] ) + r[mid] - ( sr * ( i2 - mid ) + r[y] ) > l[mid + 1] - ( sl * ( (mid + 1) - i1 ) + l[x] ) + r[mid + 1] - ( sr * ( i2 - (mid + 1) ) + r[y] ) )
		{
			st = mid + 1;
			poz = mid;
		}
		else
		{
			dr = mid - 1;
		}
	}
	
	s1 = l[poz] - ( sl * ( poz - i1 ) + l[x] ) + r[poz] - ( sr * ( i2 - poz ) + r[y] );
	if ( poz != y )
		s2 = l[poz + 1] - ( sl * ( (poz + 1) - i1 ) + l[x] ) + r[poz + 1] - ( sr * ( i2 - (poz + 1) ) + r[y] );
	else
		s2 = INF;
	
	if ( s1 < s2 )
	{
		fprintf( g, "%lld %lld\n", poz, s1 );
	}
	else
	{
		fprintf( g, "%lld %lld\n", poz + 1, s2 );
	}
}

void Next()
{
	if ( ++P == MAX )
	{
		std::fread( s, 1, MAX, f );
		P = 0;
	}
}

void Get( long long& x )
{
	for ( ; s[P] < '0' || s[P] > '9'; Next() );
	
	for ( x = 0; s[P] >= '0' && s[P] <= '9'; Next() )
		x = ( x * 10 ) + ( s[P] - '0' );
}