Balanced Lineup

【题目描述】

John有n头奶牛(1 ≤ n ≤ 50000),给定Q个询问区间(1 ≤ Q ≤ 200000)和每头奶牛的高度(1 ≤ 高度 ≤ 1000000),对于每个询问区间,询问在此区间内最高牛和最矮牛的高度差。

【输入描述】

第一行输入两个整数n、Q;

接下来n行,每行输入一个整数,表示每头牛的高度;

接下来Q行,每行输入两个整数L、R(1 ≤ L ≤ R ≤ n),表示询问区间。

【输出描述】

输出Q行,每行包含一个整数,表示在此区间内最高牛和最矮牛的高度差。

【输入样例】

6 3

1

7

3

4

2

5

1 5

4 6

2 2

【输出样例】

6

3

0

源代码:

#include<cstdio>
#include<cmath>
int m,n,k,i[50001],f1[50001][16],f2[50001][16];
int main() //稀疏表(ST表)。
{
    scanf("%d%d",&n,&m);
    for (int a=1;a<=n;a++)
    {
        scanf("%d",&i[a]);
        f1[a][0]=f2[a][0]=i[a]; 
    } //根据f[i][i]初始化初值。
    k=floor(log((double)n)/log(2.0));
    for (int a=1;a<=k;a++) //DP预处理,f[i,j]表示从第 i 点开始 2^j 个点的最值,表示区间 [i,i+(2^j)-1],则有 [i,j]=[i,j-1]∪[i+2^(j-1),j-1]。 
      for (int b=1;b+(1<<(a-1))<=n;b++) //防止越界。
      {
          f1[b][a]=f1[b][a-1]<f1[b+(1<<(a-1))][a-1]?f1[b][a-1]:f1[b+(1<<(a-1))][a-1]; //最小值。
          f2[b][a]=f2[b][a-1]>f2[b+(1<<(a-1))][a-1]?f2[b][a-1]:f2[b+(1<<(a-1))][a-1]; //最大值。
      }
    n=m;
    for (int a=1;a<=n;a++) //询问区间最值之差。
    {
        int t1,t2,s1,s2;
        scanf("%d%d",&t1,&t2);
        k=floor(log((double)(t2-t1+1))/log(2.0)); //同理进行查询。
        s1=f1[t1][k]<f1[t2-(1<<k)+1][k]?f1[t1][k]:f1[t2-(1<<k)+1][k];
        s2=f2[t1][k]>f2[t2-(1<<k)+1][k]?f2[t1][k]:f2[t2-(1<<k)+1][k];
        printf("%d\n",s2-s1);
    }
    return 0;
}
posted @ 2016-04-28 20:51  前前前世。  阅读(248)  评论(0编辑  收藏  举报