Cod sursa(job #254879)

Utilizator CezarMocanCezar Mocan CezarMocan Data 7 februarie 2009 22:39:58
Problema Cuburi2 Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.8 kb
#include <cstdio>
#define maxn 250100

using namespace std;

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

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) / 2;
		if ((s[m - 1] - s[l - 1] <= s[r] - s[m]) && (s[m] - s[l - 1] > s[r] - s[m + 1]))
			return m;
		
		if (s[m - 1] - s[l - 1] <= s[r] - s[m])
			l = m + 1;
		else
			r = m - 1;
	}
	
}

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 - 210;
		if (l1 < x)
			l1 = x;
		
		int l2 = pz + 210;
		if (l2 > y)
			l2 = y;
		
		rfin = 2000000000;
		for (poz = l1; poz <= l2; poz++) {
			rez = c[poz];
			m1 = poz - x;
			m2 = y - poz;
			rez = rez - (m1 * s[x - 1] + b[x - 1]) - (m2 * (s[n] - s[y]) + a[y + 1]);
			if (rez < rfin) {
				rfin = rez;
				cfin = poz;
			}
		}
		printf("%d %d\n", cfin, rfin);
	}
	
	
	return 0;
}