点我看题目

题意 :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

 

posted on 2014-02-25 16:28  枫、  阅读(182)  评论(0编辑  收藏  举报