Cod sursa(job #254707)

Utilizator alexeiIacob Radu alexei Data 7 februarie 2009 13:49:51
Problema Cuburi2 Scor 0
Compilator cpp Status done
Runda Stelele Informaticii 2009, clasele 9-10, ziua 2 Marime 2.65 kb
#include<stdio.h>
#define NMAX 250001

long long A[NMAX],B[NMAX],S1[NMAX],S2[NMAX];
int V[NMAX],POS[NMAX*4];
int N,M;
long long ARB[NMAX*4];
int P1,P2,val,pos;
long long A1,A2;

void reading()
{
	scanf("%d%d\n",&N,&M);

	int i;
	for(i=1; i<=N; ++i)
	{
		scanf("%d",&V[i]);
		S1[i]=S1[i-1]+V[i];
	}	
}

void update(const int nod,const int left,const int right)
{
	if( left==right )
	{
		ARB[nod]=val;
		POS[nod]=pos;
	}
	else
	{
		int mij=(left+right)>>1;
		int aux=nod<<1;

		if( pos<=mij ) update( aux, left, mij );
		else update( aux+1, mij+1, right );

		int a1,a2,p1;
		a1=ARB[aux];
		a2=ARB[aux+1];


		if( a1 && a2 ) 
			if( a1>a2 )
				a1=a2,p1=POS[aux+1];
			else
				p1=POS[aux];
		if( !a1 ) a1=a2,p1=POS[aux+1];
		else
			if( !a2 )
			p1=POS[aux];
		
		ARB[nod]=a1;
		POS[nod]=p1;
	}
}

inline long long min(const long long a,const long long b)
{
	return a<b?a:b;
}

void query(int nod,int left,int right)
{
    if( P1 <= left && P2 >= right)
	{	
		 if( A1>ARB[nod] )	
			 A1=ARB[nod],A2=POS[nod];
	}
	else
	{
         int mij=(left+right)/2;
         if( P1<=mij ) query(nod<<1,left,mij); 
         if( mij<P2) query(2*nod+1,mij+1,right);
    }
}
/*
void check(int nod,int left,int right)
{
	printf("%d %d (%d %d)\n",ARB[nod],POS[nod],left,right);
	if( left==right )
		return;
	else
	{
		int mij=(left+right)>>1;
		check( nod*2, left, mij );
		check( nod*2+1, mij+1, right );
		printf("%d %d (%d %d)\n",ARB[nod],POS[nod],left,right);
	}
}*/
void init()
{
	int i,j;
	
	for(i=N; i>=1; --i)
	{
		S2[i]=S2[i+1]+V[i];
	}

	for(i=1; i<=N; ++i,++j)
		A[i]=A[i-1]+S1[i-1];
	
	for(i=N; i>=1; --i)
		B[i]=B[i+1]+S2[i+1];
	
	for(i=1; i<=N; ++i)
	{
		pos=i;val=A[i]+B[i];
		update(1,1,N);
	}

	//check(1,1,N);
}

void find()
{
	int a1,a2;
	while( M-- )
	{
		scanf("%d%d\n",&a1,&a2);
		P1=a1;P2=a2;
		A1=0x3f3f3f3f;A2=1;
		query(1,1,N);
		printf("%d %d\n",A2,0);
	}
}

void za_brute()//you have to hate them and love them
{
	long long ANS,POS;
	int i;
	int a1,a2;
	while( M-- )
	{
		scanf("%d%d\n",&a1,&a2);
		
		ANS=0x3f3f3f3f;POS=-1;

		A[ a1-1 ]=0;S1[ a1-1 ]=0;
		B[ a2+1 ]=0;S2[ a2+1 ]=0;

		for( i=a1; i<=a2; ++i)
		{
			A[ i ]=A[ i-1 ]+S1[i-1];
			S1[i]=S1[i-1]+V[i];
		}
		for( i=a2; i>=a1; --i)
		{
			B[ i ]=B[ i+1 ]+S2[i+1];
			S2[i]=S2[i+1]+V[i];

			if( A[i]+B[i]<ANS )
			{
				ANS=A[i]+B[i];
				POS=i;
			}
		}
		printf("%lld %lld\n",POS,ANS);
	}
}
	

int main()
{
	freopen("cuburi2.in","r",stdin);
	freopen("cuburi2.out","w",stdout);
	
	reading();
	
	if( N>3000 )
	{
		init();
		find();
	}
	else
		za_brute();

	return 0;
}