POJ 3264 Balanced Lineup(RMQ)

点我看题目

题意 :N头奶牛,Q次询问,然后给你每一头奶牛的身高,每一次询问都给你两个数,x y,代表着从x位置上的奶牛到y位置上的奶牛身高最高的和最矮的相差多少。

思路 : 刚好符合RMQ的那个求区间最大最小值,所以用RMQ还是很方便的。就是一个RMQ的模板题,基本上书上网上都有。

RMQ基础知识

RMQ算法举例

#include <stdio.h>

#include <string.h>

#include <math.h>

#include <iostream>



const int maxn = 51000 ;

int maxsum[maxn][20],minsum[maxn][20] ;

int a[maxn] ;

int N,Q ;



using namespace std ;



void Init()

{

    for(int i = 1 ; i <= N ; i++)

    {

        scanf("%d",&a[i]) ;

        maxsum[i][0] = a[i] ;

        minsum[i][0] = a[i] ;

    }

}



void RMQ()

{

    int k = (int )(log((double)N)/log(2.0)) ;

    for(int j = 1 ; j <= k ; j++)

    for(int i = 1 ; i <= N ; i++)

    if(i + (1 << j) - 1 <= N )

    {

        maxsum[i][j] = max(maxsum[i][j-1],maxsum[i + (1 << (j-1))][j-1]) ;

        minsum[i][j] = min(minsum[i][j-1],minsum[i + (1 << (j-1))][j-1]) ;

    }

}

int main()

{

    while(~scanf("%d %d",&N,&Q))

    {

        Init() ;

        RMQ() ;

        int x,y ;

        for(int i = 1 ; i <= Q ; i++)

        {

            scanf("%d %d",&x,&y) ;

            int k = (int)(log((double)(y-x+1))/log(2.0)) ;

            int minn = min(minsum[x][k],minsum[y-(1<<k)+1][k]) ;

            int maxx = max(maxsum[x][k],maxsum[y-(1<<k)+1][k]) ;

            printf("%d\n",maxx-minn) ;

        }

    }

    return 0 ;

}
View Code

 线段树写法 :

 1 //POJ 3264

 2 #include <cstdio>

 3 #include <cstring>

 4 #include <iostream>

 5 

 6 using namespace std ;

 7 

 8 //int maxx,minn ;

 9 int p[50010 * 4],q[50010 * 4];

10 

11 void pushup(int rt)

12 {

13     p[rt] = max(p[rt << 1],p[rt << 1 | 1]) ;

14     q[rt] = min(q[rt << 1],q[rt << 1 | 1]) ;

15 }

16 void build(int l,int r,int rt)

17 {

18     int a ;

19     if(l == r)

20     {

21         scanf("%d",&a) ;

22         p[rt] = a ;

23         q[rt] = a ;

24         return ;

25     }

26     int mid = (l+r) >> 1;

27     build(l,mid,rt << 1) ;

28     build(mid+1,r,rt << 1 | 1) ;

29     pushup(rt) ;

30 }

31 int query(int L,int R,int l,int r,int rt)

32 {

33     int maxx = -1 ;

34     if(l >= L && r <= R)

35     {

36         return p[rt] ;

37     }

38     int mid = (l+r) >> 1 ;

39     if(mid >= L)

40         maxx = max(maxx,query(L,R,l,mid,rt << 1) ) ;

41     if(mid < R)

42         maxx = max(maxx,query(L,R,mid+1,r,rt << 1 | 1)) ;

43     return maxx ;

44 }

45 int querz(int L,int R,int l,int r,int rt)

46 {

47    int minn = 99999999 ;

48     if(l >= L && r <= R)

49     {

50         return q[rt] ;

51     }

52     int mid = (l+r) >> 1 ;

53     if(mid >= L)

54         minn = min(minn,querz(L,R,l,mid,rt << 1) ) ;

55     if(mid < R)

56         minn = min(minn,querz(L,R,mid+1,r,rt << 1 | 1) );

57     return minn ;

58 }

59 int main()

60 {

61     int N,M ;

62     while(~scanf("%d %d",&N,&M))

63     {

64         build(1,N,1) ;

65         int a,b ;

66         for(int i = 0 ; i < M ; i++)

67         {

68             scanf("%d %d",&a,&b) ;

69           //  printf("%d %d*\n",query(a,b,1,N,1),querz(a,b,1,N,1)) ;

70             printf("%d\n",query(a,b,1,N,1) - querz(a,b,1,N,1) ) ;

71         }

72     }

73     return 0 ;

74 }
View Code

 

你可能感兴趣的:(poj)