POJ3264

RMQ 的模板题


RMQ算法是求区间内最大值和最小值的问题


#include <iostream>

#include <stdio.h>
#include <string.h>
#include <math.h>


using namespace std;


int num [50000 + 50];
int dmin[50000 + 50][20];
int dmax[50000 + 50][20];
int n,k,q;


void RMQ()
{
    for( int i = 1; i<=n; i++)
     dmin[i][0] = dmax[i][0] = num[i];


     for( int i = 1; (1<<i) <= n ; i++)
     {
         for( int j = 1; j<= n; j++)
          {
              if(j + (1<<i) -1 <= n)
              {
                  //cout<<j<<"  "<<i<<"   ";
                  dmin[j][i] = min(dmin[j][i-1],dmin[j+(1<<(i-1)) ][i-1]);
                 // cout<<dmin[j][i]<<"dmin";
                  dmax[j][i] = max(dmax[j][i-1],dmax[j+(1<<(i-1)) ][i-1]);
                  //cout<<dmax[j][i]<<"dmax"<<endl;
              }
          }
     }
}


int get(int a, int b)
{
    while((1<<(k+1)) <= b - a + 1)  // K是满足(1<<(K+1))<b-a+1的最大值因为dmax//dmin数组里DMIN[I][J]存的是I 到 I + 1 <<(J-1)所以K要满足(1<<(k+1)) <= b - a + 1) 
      k++;
    int ans1 = max(dmax[a][k], dmax[b - (1<<k)+1][k]);
    int ans2 = min(dmin[a][k], dmin[b - (1<<k)+1][k]);


    return ans1- ans2;
}


int main()
{
    memset(num,0,sizeof(num));
    int L,H;
    while(scanf("%d %d",&n, &q)!= EOF)
    {
        for( int i = 1; i <= n; i++)
             cin>>num[i];


       RMQ();
       for( int i = 0; i<q; i++)
       {
          
           scanf("%d %d",&L, &H);
           k = 0;
           cout<<get(L,H)<<endl;
       }
    }
    return 0;

}


//一位把1<<i写成i<<1RE了无数次,为什么我写代码不能认真点呢

你可能感兴趣的:(POJ3264)