洛谷P3865【模板】ST 表

题目申明:

本题是洛谷的P3865号题目,题目传送门:P3865 【模板】ST 表 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)icon-default.png?t=N7T8https://www.luogu.com.cn/problem/P3865

简介:

ST表是离线算法

注:离线的意思是查找区间内的数值不会改变,如果会改变的话,称为在线,如果用ST表来解在线的题目的话,时间复杂度可能达不到要求。

思路:

使用二维dp达成目地

dp方法:

dp[i][j]---表示从i位置开始(个数)为2^j区间的最值

dp[L_i][ L_j]=max_L

dp[R_i][R_j]=max_R

dp[L_i][R_j]=max(dp[L_i][L_j], dp[R_i][R_j])

由此得出dp公式:

dp[i][j]=max(dp[i][j-1],dp[i+2^(j-1)][j-1])

也可以这么写:

       dp[i][j]=max(dp[i][j-1],dp[i+(1<<(j-1))][j-1])

代码:

#include<bits/stdc++.h>

using namespace std;

int main(){

//预处理,时间复杂度为O(nlogn)

       int n,m;

       cin>>n>>m;

       vector<vector<int>> dp(n+1,vector<int>(20));

       vector<int> log2(n+1,-1);

       for(int i=1;i<=n;i++){

              scanf("%d",&dp[i][0]);//从i到(个数)2^0=1,也就是长度是1,这个区间里只有一个数,最大的数就是他自己

       }

       for(int i=1;i<=n;i++){

              log2[i]=log2[i>>1]+1;//手动实现log

       }

       //j之所以放在前面是因为dp的高维(dp的第二个"[]")还没计算出来

       for(int j=1;(1<<j)<=n;j++){//(1<<j)<=n是判断循环里最大的j是否大于n

              for(int i=1;i+(1<<(j))-1<=n;i++){

                     dp[i][j]=max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);//联系图1,i+(1<<(j-1))是R_i的意思

              }

       }

      

//得出查找max时间复杂度为O(1)的结果

       int l,r;

       for(int i=0;i<m;i++){

              scanf("%d%d",&l,&r);

              int k=log2[r-l+1];

              printf("%d\n",max(dp[l][k],dp[r-(1<<k)+1][k]));

       }

       return 0;

}

  • 16
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值