Cod sursa(job #261992)

Utilizator savimSerban Andrei Stan savim Data 18 februarie 2009 22:00:01
Problema Cuburi2 Scor 60
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.98 kb
#include <stdio.h>

#define MAX_N 250010
#define LL long long

int n, m, i, j, left, right, r, p, q;
LL val[4];
LL v[MAX_N], nr_st[MAX_N], nr_dr[MAX_N], st[MAX_N], dr[MAX_N], rez;

void prec_st() {
	for (i = 1; i <= n; i++) {
		nr_st[i] = nr_st[i - 1] + v[i];
		st[i] = st[i - 1] + nr_st[i - 1];
	}
}

void prec_dr() {
	for (i = n; i >= 1; i--) {
		nr_dr[i] = nr_dr[i + 1] + v[i];
		dr[i] = dr[i + 1] + nr_dr[i + 1];
	}
}

void cit() {
	freopen("cuburi2.in", "r", stdin);
	freopen("cuburi2.out", "w", stdout);
	
	scanf("%d %d", &n, &m);
	for (i = 1; i <= n; i++)
		scanf("%lld", &v[i]);
	prec_st();
	prec_dr();
}

long long calc(int left, int right, int poz) {
	//vad in O(1) costul pentru a aduce toate elementele din intervalul left right pe poz
	
	//aduc intervalul left..poz pe pozitia poz
	rez = st[poz] - st[left - 1] - nr_st[left - 1] * (poz - left + 1);
	
	//aduc intervalul poz..dr pe pozitia poz
	rez += dr[poz] - dr[right + 1] - nr_dr[right + 1] * (right - poz + 1);
	
	if (poz < left || poz > right) rez = 1LL * (1 << 30) * (1 << 30);
	
	return rez;
}

void solve() {
	for (i = 1; i <= m; i++) {
		scanf("%d %d", &left, &right);
		
		p = left - 1; q = right + 1;
		
		//iau cazurile particulare, in care sirul e strict crescator / descrescator
		if (calc(left, right, left) <= calc(left, right, left + 1))
			printf("%d %lld\n", left, calc(left, right, left));
		else 
			if (calc(left, right, right) <= calc(left, right, right - 1))
				printf("%d %lld\n", right, calc(left, right, right));
			else 
				while (p + 1 < q) {
					r = (p + q) / 2;
					
					val[1] = r - 1;	val[2] = r;	val[3] = r + 1;
					
					for (j = 1; j <= 3; j++)
						val[j] = calc(left, right, val[j]);
					
					if (val[1] >= val[2] && val[2] <= val[3]) {
						printf("%d %lld\n", r, val[2]);
						break;
					}
					else if (val[1] <= val[2] && val[2] <= val[3]) q = r;
						 else p = r;
				}
	}
}

int main() {

	cit();
	solve();
	
	return 0;
}