Cod sursa(job #256084)

Utilizator andrei-alphaAndrei-Bogdan Antonescu andrei-alpha Data 11 februarie 2009 01:14:33
Problema Cuburi2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.81 kb
using namespace std;

#include <bitset>
#define f first
#define s second
#define II inline
#define ll long long
#define FOR(i,a,b) for(int i=a;i<=b;++i)
#define FOL(i,a,b) for(int i=a;i>=b;--i)
#define mp make_pair
#define IN  "cuburi2.in"
#define OUT "cuburi2.out"
#define N_MAX 1<<18
#define abs(x) ((x)<0?(-(x)):(x))

int N,M,x,y;
int V[N_MAX];
ll L[N_MAX],R[N_MAX],S[N_MAX],SR[N_MAX],SL[N_MAX];

II void scan()
{
	freopen(IN,"r",stdin);
	freopen(OUT,"w",stdout);
	scanf("%d%d\n",&N,&M);
	
	FOR(i,1,N)
		scanf("%d",V+i);
}

II ll suma(int poz)
{
	return S[poz] - L[x-1] - SL[x-1] * (ll)(poz-x) - R[y+1] - SR[y+1] * (ll)(y-poz);
}

II pair<ll,ll> find()
{
	int a = x, b = y;  
    int m = x;  

    for(int mij;a <= b;)  
    {  
        mij = (a+b) >> 1;  

        if (SL[mij-1] - SL[x-1] < SL[y] - SL[mij-1])  
        {  
            a = mij + 1;  
            m = mij;  
        }  
        else 
			b = mij - 1;  
    }  
	return mp(m,suma(m));
}

II pair<ll,ll> find2()
{
	int m,step;
	for(step = 1;step <= N;step <<= 1);
	for(m=x;step;step >>= 1)
	{
		if(m + step <= y && suma(m) > suma(m+step) )
			m += step;
		if(m - step >= x && suma(m) > suma(m-step) )
			m -= step;
	}
	return mp(m,suma(m));
}

II void compute()
{
	FOL(i,N,1)
		SR[i] = SR[i+1] + V[i];
	FOR(i,1,N)
		SL[i] = SL[i-1] + V[i];
	
	ll sum(0);
	FOR(i,2,N)
		sum += (ll)V[i] * (i-1);
	
	FOR(i,1,N)
	{
		S[i] = sum;
		sum += SL[i];
		sum -= SR[i+1];
	}	
	FOR(i,1,N)
		L[i] = L[i-1] + SL[i];
	FOL(i,N,1)
		R[i] = R[i+1] + SR[i];
}

II void solve()
{
	FOR(i,1,M)  
    {  
        scanf("%d%d\n",&x,&y);  
        pair<ll,ll> rez = find();  
        printf("%lld ",rez.f);  
		printf("%lld\n",rez.s);  
    }  
}

int main()
{
	scan();
	compute();
	solve();
	return 0;
}