Cod sursa(job #403922)

Utilizator perticas_catalinperticas catalin perticas_catalin Data 25 februarie 2010 16:17:00
Problema Cuburi2 Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.57 kb
#include<iostream>
#include<string>

using namespace std;

#define NM 250005
#define LL long long
#define maxbuf 65536

FILE*fin=fopen("cuburi2.in","r");

int N,M;

int A[NM];

LL UL[NM],UR[NM],TL[NM],TR[NM];

int ind;
char buf[maxbuf];

inline void refbuf()
{
     int ans=fread(buf,1,maxbuf,fin);
     if(ans<maxbuf) buf[ans]=0;
     ind=0;  
}

inline int getnr()
{
     int ans=0;
     
     one:
         while(ind<maxbuf && !isdigit(buf[ind])) ++ind;
         if(ind==maxbuf)
         {
              refbuf();
              goto one;          
         }  
     two:
         while(ind<maxbuf && isdigit(buf[ind]))
         {
              ans=ans*10+buf[ind]-'0';
              ++ind;
         }    
         if(ind==maxbuf)
         {
              refbuf();
              goto two;
         }
     return ans;    
}

inline LL retsum(int x,int y,int t)
{
     LL ans=0;  
     ans+=(TL[t]-TL[x-1]-UL[x-1]*(t-x+1));
     ans+=(TR[t]-TR[y+1]-UR[y+1]*(y-t+1));
     
     return ans;  
}

int main()
{
    int x,y;
    
    //freopen("cuburi2.in","r",stdin);
    freopen("cuburi2.out","w",stdout);
    
    refbuf();
    
    N=getnr();
    M=getnr();
    
    for(int i=1;i<=N;++i)
       A[i]=getnr();
    
    for(int i=1;i<=N;++i)
       UL[i]=UL[i-1]+A[i];
    
    for(int i=N;i>=1;--i)
       UR[i]=UR[i+1]+A[i];
       
    for(int i=1;i<=N;++i)
       TL[i]=TL[i-1]+UL[i-1];
       
    for(int i=N;i>=1;--i)
       TR[i]=TR[i+1]+UR[i+1];         
    
    for(int i=1;i<=M;++i)
    {
       x=getnr();
       y=getnr();
            
       LL best;
       int pos;
       
       LL vs=retsum(x,y,x);
       LL vd=retsum(x,y,y);
       
       if(vs>vd) 
       {
           best=vs;
           pos=x;
       }
       else 
       {
           best=vd;
           pos=y;
       }
       
       int st=x,dr=y;
       
       while((dr-st)>17)
       {
           int lt=(2*st+dr)/3;
           int rt=(st+2*dr)/3;
           
           LL lv=retsum(x,y,lt);
           LL rv=retsum(x,y,rt);
           
           if(lv<rv) dr=rt;
           else st=lt;            
       }
       
       /*
       for(int j=x;j<=y;++j)
          printf("%I64d ",retsum(x,y,j));
       */
       
      
       for(int j=st;j<=dr;++j)
       {
           LL cur=retsum(x,y,j);
           if(cur<best)
           {
              best=cur;
              pos=j;
           }
       }
       
       printf("%d %lld",pos,best);
       
       printf("\n");
    }
    
    return 0;
}