ST算法模板题poj3264

题目链接


http://poj.org/problem?id=3264
 题目意为给定一串数组,求某个区间范围内的最大值和最小值之差。
 由于询问数量较多,并且也不涉及更新值,所以使用st求RMQ预处理最大和最小。
 此题用来学习ST算法,j表示包含i的i后2^j个数的最大值,可以知道,dp[i][j]可以被拆分成两部分dp[i][j - 1]和dp[i + (1<<(j - 1))][j - 1]这样就可以更新出所有的dp。询问时只要求出一个最大的j使y - x + 1大于2^j即可将询问拆分成dp[x][j]和dp[y - (1<< j) + 1][j]。o(1)查询就实现了。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#define rep(i, s, t) for(int i = s;i <= t;i++)
#define rap(i, s, t) for(int i = s;i >= t;i--)
using namespace std;
int n, q;
int a[50004];
int maxx[50004][32], minx[50004][32];
void ST(int n)
{
    rep(i, 1, n){
        maxx[i][0] = minx[i][0] = a[i];
    }
    int k = log(n * 1.0) / log(2.0);
    rep(j, 1, k){
        rep(i, 1, n){
            if(i + (1<<(j - 1)) > n) break;
            maxx[i][j] = max(maxx[i][j - 1], maxx[i + (1<<(j - 1))][j - 1]);
            minx[i][j] = min(minx[i][j - 1], minx[i + (1<<(j - 1))][j - 1]);
        }
    }
}
int get_Ans(int x, int y)
{
    int k = log(y - x + 1.0) / log(2.0);
    return max(maxx[x][k], maxx[y - (1<<k) + 1][k]) - min(minx[x][k], minx[y - (1<<k) + 1][k]);
}
int main()
{
    while(cin>>n>>q)
    {
        rep(i, 1, n){
            scanf("%d", &a[i]);
        }
        memset(maxx, 0, sizeof(maxx));
        memset(minx, 0, sizeof(minx));
        ST(n);
        rep(i, 1, q){
            int st, en;
            scanf("%d%d", &st, &en);
            printf("%d\n", get_Ans(st, en));
        }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值