Cod sursa(job #377856)

Utilizator perticas_catalinperticas catalin perticas_catalin Data 26 decembrie 2009 18:07:23
Problema Struti Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.95 kb
#include<iostream>
#include<string>

using namespace std;

#define maxbuf 65536
#define NM 1005
#define inf 1000000
#define FOR(i,a,b)for(int i=(a);i<=(b);++i)

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

char buf[maxbuf];

int ind,ter[NM][NM],deq[NM][NM][2],best,cate,dmin[NM],dmax[NM],stm,drm,stM,drM;

int N,M,P;

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

inline int readnr()
{
     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 int empty(int c1,int c2)
{
    if(deq[c2][1][c1]-deq[c2][0][c1]<0) return 1;
    return 0;   
}

inline void insert(int c1,int c2,int p)
{
    ++deq[c2][1][c1];
    deq[c2][deq[c2][1][c1]][c1]=p;
}

inline void erase(int c1,int c2)
{
    ++deq[c2][0][c1];   
}

inline int right(int c1,int c2)
{
  return deq[c2][deq[c2][1][c1]][c1];
}

inline int left(int c1,int c2)
{
  return deq[c2][deq[c2][0][c1]][c1];
}

inline void insmax(int care,int p)
{
    while(!empty(1,care) && ter[care][right(1,care)]<=ter[care][p]) --deq[care][1][1];
    insert(1,care,p);   
}
inline void insmin(int care,int p)
{
    while(!empty(0,care) && ter[care][right(0,care)]>=ter[care][p]) --deq[care][1][0];
    insert(0,care,p);
}
void solve(int L,int C)
{
     FOR(i,1,M)
     {
       deq[i][0][0]=2;
       deq[i][1][0]=1;
       deq[i][0][1]=2;
       deq[i][1][1]=1;
     }  
     
     FOR(i,1,M)
       FOR(j,1,L-1)
       {
         insmax(i,j);
         insmin(i,j);
       }  
     
     FOR(i,L,N)
     {
       //scoateri        
               
       FOR(j,1,M)
       {
         if(left(0,j)==i-L) erase(0,j);
         if(left(1,j)==i-L) erase(1,j);
       }  
         
       //inserari  
       
       FOR(j,1,M)
       {
         insmin(j,i);
         insmax(j,i);
       }
       
       //baleiez pe orizontala
       
       stm=0;drm=-1;
       stM=0,drM=-1;
       
       FOR(j,1,C-1)
       {
         //inserez minimul
         
         while(drm-stm>=0 && ter[j][left(0,j)]<=ter[dmin[drm]][left(0,dmin[drm])]) --drm;
         dmin[++drm]=j;
         
         //inserez maximul
         
         while(drM-stM>=0 && ter[j][left(1,j)]>=ter[dmax[drM]][left(1,dmax[drM])]) --drM;
         dmax[++drM]=j;
       }
       
       FOR(j,C,M)
       {
         //scoateri
         
         if(dmin[stm]==j-C) ++stm;
         if(dmax[stM]==j-C) ++stM;
         
         //inserez minimul
         
         while(drm-stm>=0 && ter[j][left(0,j)]<=ter[dmin[drm]][left(0,dmin[drm])]) --drm;
         dmin[++drm]=j;
         
         //inserez maximul
         
         while(drM-stM>=0 && ter[j][left(1,j)]>=ter[dmax[drM]][left(1,dmax[drM])]) --drM;
         dmax[++drM]=j;
         
         //update-uri
         
         int ansc=ter[dmax[stM]][left(1,dmax[stM])]-ter[dmin[stm]][left(0,dmin[stm])];
         
         if(ansc<best)
         {
           best=ansc;
           cate=1;
         }
         else if(ansc==best) ++cate;
       }
     }  
         
}

int main()
{
    int DX,DY;
    
    //freopen("struti.in","r",stdin);
    freopen("struti.out","w",stdout);
    
    refbuf();
    
    N=readnr();
    M=readnr();
    P=readnr();
    
    FOR(i,1,N)
      FOR(j,1,M)
        ter[i][j]=readnr();
    
    while(P--)
    {
      best=inf,cate=0;        
              
      DX=readnr();
      DY=readnr();
      
      solve(DX,DY);
      if(DX!=DY) solve(DY,DX);
      
      printf("%d %d\n",best,cate);
    }    
    
    return 0;
}