zoukankan      html  css  js  c++  java
  • Poj 3264 Balanced Lineup RMQ模板

    题目链接:

      Poj 3264 Balanced Lineup

    题目描述:

      给出一个n个数的序列,有q个查询,每次查询区间[l, r]内的最大值与最小值的绝对值。

    解题思路:

      很模板的RMQ模板题,在这里总结一下RMQ:RMQ(Range Minimum/Maximum Query) 即区间最值查询,是指这样一个问题:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在i,j之间的最小/大值。

      RMQ有三种求法:1:直接遍历查找,炒鸡暴力;

               2:线段树也可以解决这一类问题;

               3:ST(Sparse Table)算法:在线处理RMQ问题,可以做到O(n*log(n))内预处理,O(1)内查询到所要结果。

      对于ST(Sparse Table)算法,预处理的时候用的是DP思想,用一个二维数组dp[i][j]记录区间[i,i+2^j-1] (持续2^j个)区间中的最小值(其中dp[i,0] = a[i])

      对于任意的一组(i,j),dp[i][j] = min{dp[i][j-1],dp[i+2^(j-1)][j-1]}来使用动态规划计算出来。最优美的地方还在与查询的时候,对于区间[m, n],可以找到一个k,k满足 n-m+1 < 2^(k+1),然后ans = min {dp[m][m+2^k-1],  [n-2^k+1][n]},区间[m,m+2^k-1]和[n-2^k+1,n]内的最值我们是预处理过的,所以在O(1)的时间内就可以找到ans咯。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 using namespace std;
     6 
     7 const int maxn = 50010;
     8 int dmin[maxn][18], dmax[maxn][18];
     9 int arr[maxn];
    10 
    11 void RMQ_init (int n)
    12 {
    13     for (int i=0; i<n; i++)
    14         dmin[i][0] = dmax[i][0] = arr[i];
    15 
    16     for (int j=1; (1<<j)<=n; j++)
    17         for (int i=0; i+(1<<j)-1<n; i++)
    18         {
    19             dmin[i][j] = min (dmin[i][j-1], dmin[i+(1<<(j-1))][j-1]);
    20             dmax[i][j] = max (dmax[i][j-1], dmax[i+(1<<(j-1))][j-1]);
    21         }
    22 }
    23 int solve (int a, int b)
    24 {
    25     int x = 0;
    26     while (1<<(x+1) <= b-a+1)    x++;
    27     int Max = max (dmax[a][x], dmax[b-(1<<x)+1][x]);
    28     int Min = min (dmin[a][x], dmin[b-(1<<x)+1][x]);
    29     return Max - Min;
    30 }
    31 
    32 int main ()
    33 {
    34     int n, q, a, b;
    35     while (scanf ("%d %d", &n, &q) != EOF)
    36     {
    37         for (int i=0; i<n; i++)
    38             scanf ("%d", &arr[i]);
    39         RMQ_init( n );
    40         while (q --)
    41         {
    42             scanf ("%d %d", &a, &b);
    43             printf ("%d
    ", solve(a-1, b-1));
    44         }
    45     }
    46     return 0;
    47 }
    本文为博主原创文章,未经博主允许不得转载。
  • 相关阅读:
    [Codeforces 140C] New Year Snowmen
    [Codeforces Round511C] Enlarge GCD
    [BZOJ 1251] 序列终结者
    [NOIP 2016] 愤怒的小鸟
    [POJ 1860] Currency Exchange
    [ZJOI 2006] 书架
    [NOIP 2010] 引入入城
    [NOI 2014] 起床困难综合征
    用C语言实现中文到unicode码的转换
    strdup与strndup
  • 原文地址:https://www.cnblogs.com/alihenaixiao/p/4783683.html
Copyright © 2011-2022 走看看