POJ 3264 (ST表的简单使用)

来源:互联网 发布:淘宝有种苗吗 编辑:程序博客网 时间:2024/06/04 19:34

题意:

给一个数列,有Q个查询,每次查询L,R区间的最大值和最小值,输出他们的差。

思路:

st表对于区间查询来说是特别方便的,维护两个二维数组,分别是代表某一个区间的最>大值和最小值,st[i][j] 表示第i个数字和其之后的2^j 个数字的最值。那么二重循环进
行比较。

  • 值得一说的是:st用到的是二进制的运算,其快速是一个特点。具体函数看代码。
    #include <iostream>    #include <cstdio>    using namespace std;    const int maxn = 50005;    int n,q;    int st1[maxn][30];    int st2[maxn][30];    void RMQ_inti()    {        for(int j = 1;(1 << j) <= n; j++) {            for(int i = 0;i + (1<<j) - 1 < n; i++) {                st1[i][j] = min(st1[i][j-1],st1[i + (1<<(j-1))][j-1]);                st2[i][j] = max(st2[i][j-1],st2[i + (1<<(j-1))][j-1]);            }        }    }    int RMQ1(int l,int r)    {        int k = 0;        while((1<<(k+1)) <= r - l + 1) k++;        return min(st1[l][k],st1[r-(1<<k)+1][k]);    }    int RMQ2(int l,int r)    {        int k = 0;        while((1<<(k+1)) <= r - l + 1) k++;        return max(st2[l][k],st2[r-(1<<k)+1][k]);    }    int main()    {        //freopen("in.txt","r",stdin);        scanf("%d%d",&n,&q);        for(int i = 0;i < n; i++) {            scanf("%d",&st1[i][0]);            st2[i][0] = st1[i][0];        }        RMQ_inti();        int ans1,ans2;        for(int i = 0;i < q; i++) {            int l,r;            scanf("%d%d",&l,&r);            ans1 = RMQ1(l-1,r-1);            ans2 = RMQ2(l-1,r-1);            printf("%d\n",ans2-ans1);        }        return 0;    }