zoukankan      html  css  js  c++  java
  • POJ 3264 Balanced Lineup (区间最值问题)

     

    Description

    For the daily milking, Farmer John's N cows (1 ≤ N ≤ 50,000) always line up in the same order. One day Farmer John decides to organize a game of Ultimate Frisbee with some of the cows. To keep things simple, he will take a contiguous range of cows from the milking lineup to play the game. However, for all the cows to have fun they should not differ too much in height.

    Farmer John has made a list of Q (1 ≤ Q ≤ 200,000) potential groups of cows and their heights (1 ≤ height ≤ 1,000,000). For each group, he wants your help to determine the difference in height between the shortest and the tallest cow in the group.

    Input

    Line 1: Two space-separated integers, N and Q
    Lines 2..N+1: Line i+1 contains a single integer that is the height of cow i 
    Lines N+2..N+Q+1: Two integers A and B (1 ≤ A ≤ B ≤ N), representing the range of cows from A to B inclusive.

    Output

    Lines 1..Q: Each line contains a single integer that is a response to a reply and indicates the difference in height between the tallest and shortest cow in the range.

    Sample Input

    6 3
    1
    7
    3
    4
    2
    5
    1 5
    4 6
    2 2

    Sample Output

    6
    3
    0


    思路:题目意思是查询给定区间最大值与最小值的差值,是一个典型的ST算法,RMQ区间最值查询问题。
    给定一个长度为N的数列 ST算法能在 O(NlogN)时间的预处理后,o(1)查询指定区间最值。



     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cmath>
     5 #include<algorithm>
     6 #include<map>
     7 #include<set>
     8 #include<vector>
     9 #include<queue>
    10 #include<list>
    11 //#include<unordered_map>
    12 #include<stack>
    13 using namespace std;
    14 #define ll long long 
    15 const int mod=1e9+7;
    16 const int inf=1e9+7;
    17 
    18 const int maxn=1e5+5;
    19 
    20 int num[maxn];
    21 
    22 int f_max[maxn][30];
    23 int f_min[maxn][30];
    24 
    25 int n,op;
    26 
    27 //设f[i][j]表示数列中下标在子区间[i,i+2^j -1]里的数的最值。
    28 //也就是从i开始的2^j个数的最值。
    29 //递推边界显然是f[i][0]=num[i]
    30 //即数列在子区间[i,i]里的最大值 
    31 
    32 void ST_prework()
    33 {
    34     for(int i=1;i<=n;i++)
    35     {
    36         f_max[i][0]=num[i];
    37         f_min[i][0]=num[i];
    38     }
    39     int t=log2(n)+1;
    40     for(int j=1;j<t;j++)
    41     {
    42         for(int i=1;i<=n-(1<<j)+1;i++)
    43         {   //在递推时,我们把子区间的长度成倍增长 
    44             f_max[i][j]=max(f_max[i][j-1],f_max[i+(1<<(j-1))][j-1]);
    45             f_min[i][j]=min(f_min[i][j-1],f_min[i+(1<<(j-1))][j-1]);
    46             //即长度为2^j的子区间的最值是左右两半长度为2^(j-1)的子区间的最值中较大或较小的一个 
    47         }
    48     }
    49 
    50  } 
    51  
    52 //在询问任意区间[left,right]的最值时,我们先计算一个k值,
    53 //满足2^k<right-left+1<=2^(k+1)
    54 //也就是使2的k次幂小于区间长度的前提下的最大的k
    55 //那么"从left开始的2^k个数"和"以right结尾的2的^k个数"
    56 //这两段一定覆盖了整个区间 
    57  
    58 int ST_query(int left,int right)
    59 {
    60     int k=log2(right-left+1);
    61     return  max(f_max[left][k],f_max[right-(1<<k)+1][k]) - min(f_min[left][k],f_min[right-(1<<k)+1][k]) ;
    62 }
    63 
    64 
    65 int main()
    66 {
    67 //    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    68     
    69     scanf("%d%d",&n,&op);
    70     
    71     for(int i=1;i<=n;i++)
    72         scanf("%d",&num[i]);
    73         
    74     ST_prework();
    75     
    76     int left,right;
    77     
    78     for(int i=0;i<op;i++)
    79     {
    80         scanf("%d%d",&left,&right);
    81         
    82         printf("%d
    ",ST_query(left,right));
    83     }
    84     
    85     return 0;
    86 }


    大佬见笑,,
  • 相关阅读:
    DEBIAN下中文显示
    SpringMVC整合Quartz实现定时任务以及Tomcat服务执行初始化定时任务
    SpringMVC 配置定时执行任务
    Mybatis update In
    mybatis在xml文件中处理大于号小于号的方法
    解决Cannot change version of project facet Dynamic web module to 2.5
    android 圆角边框及图片
    Android MotionEvent事件响应机制
    android:configChanges属性
    Android之ScrollView嵌套ListView
  • 原文地址:https://www.cnblogs.com/xwl3109377858/p/11330647.html
Copyright © 2011-2022 走看看