Cod sursa(job #289661)

Utilizator CezarMocanCezar Mocan CezarMocan Data 26 martie 2009 21:23:13
Problema Cuburi2 Scor 100
Compilator cpp Status done
Runda aa Marime 1.86 kb
#include <cstdio>
#define maxn 250100
#define inf 100000000000000000LL

using namespace std;

long long a[maxn], b[maxn], s[maxn], c[maxn];
int v[maxn];
int i, j, n, m, poz, x, y;
long long m1, m2, rez, rfin, cfin;

inline int cb(int l, int r) {
	int m;
	//tratez cazurile particulare in care poz va fi pe l sau pe r
	if (v[l] >= s[r] - s[l])
		return l;
	if (v[r] >= s[r - 1] - s[l - 1])
		return r;
		
	while (l <= r) {
		m = (l + r) >> 1;
		if ((s[m] - s[x - 1] <= s[y] - s[m]) && (s[m + 1] - s[x - 1] > s[y] - s[m + 1]))
			return m;
		
		if (s[m] - s[x - 1] <= s[y] - s[m])
			l = m;
		else
			r = m;
	}
	
}

int main() {
	freopen("cuburi2.in", "r", stdin);
	freopen("cuburi2.out", "w", stdout);
	
	scanf("%d%d", &n, &m);
	for (i = 1; i <= n; i++) 
		scanf("%d", &v[i]);
	
	//bag prep
	for (i = 1; i <= n; i++)
		s[i] = s[i - 1] + v[i];
	
	//a[i] e pentru partea dreapta, si b[i] pentru partea stanga
	//mai am nevoie de c[i], care reprezinta costu total daca el e buricu
	for (i = 1; i <= n; i++) 
		b[i] = b[i - 1] + s[i - 1] + v[i];
	
	for (i = n; i >= 1; i--) 
		a[i] = a[i + 1] + s[n] - s[i] + v[i];
	
	for (i = 1; i <= n; i++)
		c[i] = a[i + 1] + b[i - 1];
	
	for (i = 1; i <= m; i++) {
		scanf("%d%d", &x, &y);
		poz = cb(x, y);
		int pz = poz;
		//stiu ca am centrul la pozitia poz :>
		//acuma trebuie sa vad care e costul lui total si apoi sa scad stuff
		//in m1 si m2 tin cu cat inmultesc sumele
		int l1 = pz - 7;
		if (l1 < x)
			l1 = x;
		
		int l2 = pz + 7;
		if (l2 > y)
			l2 = y;
		
		rfin = inf;
		for (poz = l1; poz <= l2; poz++) {
			rez = c[poz];
			m1 = poz - x;
			m2 = y - poz;
			rez = rez - (1LL * m1 * s[x - 1] + b[x - 1]) - (1LL * m2 * (s[n] - s[y]) + a[y + 1]);
			if (rez < rfin) {
				rfin = rez;
				cfin = poz;
			}
		}
		printf("%lld %lld\n", cfin, rfin);
	}
	
	
	return 0;
}