luogu P3865 【模板】ST表

本文深入解析ST表模板在解决区间最值问题中的应用,介绍其递推思想及算法特性,如不支持区间内单点值修改,建表与查询的时间复杂度。通过实例代码演示如何构建和使用ST表,适用于快速查询固定长度区间内的最大值。

luogu P3865 【模板】ST表

利用递推解决区间最值问题

建成后,不支持修改区间上某一点的值

建表O(nlogn),查询O(1)

 

1<< t == 二的 t 次方

p[ k ][ i ]==从 i 开始包括 i 长为 2^k 的区间的最值

p[ 0 ][ i ]即为 a[ i ]的值本身

 

1.建表时

    区间[ i , i + 2^k -1 ] 最值等于区间[ i , i +2( k-1 )-1 ]与区间 [ i +2( k -1) ][ i + 2^k -1]的最值

p[k][i]=max(p[k-1][i],p[k-1][i+(1<<(k-1))])

    最开始知道所有的 p[ 0 ][ i ],用 p[ 0 ][ i ]去推 p[ 1 ][ i ]直到到 p[ t ][ i ]

2.询问时

    区间[ l ,r ]最值等于区间[ l , l +2^k -1]与区间[ r -2^k +1 , r ]的最值

    由于k 取log2( r - l +1)向下取整,p[ k ][ l ]与p[ t ][ r – (1 << t) + 1]取最值返回

    2^(k+1)一定能包含整个区间[ l ,r ],所以这两个 P 数组所代表的区间,一定会覆盖所求区间,且不会越界

 

#include<cstdio>
#include<cmath>      //log2()函数需调用<cmath>
#include<iostream>   //max,min,swap调用<iostream>
using namespace std;
int n,m;
int p[50][100001],a[100001];
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    for(int i=1;i<=n;i++) p[0][i]=a[i];
    int t=log2(n);
    for(int k=1;k<=t;k++)   //建表
        for(int i=1;i+(1<<k)-1<=n;i++)
            p[k][i]=max(p[k-1][i],p[k-1][i+(1<<(k-1))]);int l,r;
    for(int i=1;i<=m;i++)   //询问
    {
        scanf("%d%d",&l,&r);
        t=log2(r-l+1);
        printf("%d\n",max(p[t][l],p[t][r-(1<<t)+1]));
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/QAQq/p/10301856.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值