@zhshh
2018-07-22T04:32:30.000000Z
字数 1002
阅读 851
@zhshh OI cpp 数据结构
模板题
P3865 【模板】ST表
实质也是DP,利用倍增获取从i开始长度为的区间内的最大值。
这样对于任意区间都有,令则有这样在区间完全覆盖了这个区域(中间可能有重叠)
#include <iostream>#include <cmath>#include <cstdio>using namespace std;int dp[100100][20];int a[100100];int lg[100100];int n,m;void st(){for(int i=1;i<=n;i++){dp[i][0]=a[i];}for(int j=1;(1<<j)<=n;j++){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]);}}// 方法2// int k=0;// for(int i=1;i<=n;i++){// if(i<=(1<<(k))){// lg[i]=k;// }else{// k++;// lg[i]=k;// }// }}int RMQ(int l,int r){int k=0;// 方法2// k=lg[r-l+1]-1;// 方法3// while((1<<(k+1))<=r-l+1){// k++;// }// 方法1k=(double)log(r-l+1)/log(2);return max(dp[l][k],dp[r-(1<<k)+1][k]);}void init(){cin>>n>>m;for(int i=1;i<=n;i++){scanf("%d",&a[i]);}}int main(){init();st();// cout<<RMQ(1,5);int q,w;for(int i=1;i<=m;i++){scanf("%d%d",&q,&w);printf("%d\n",RMQ(q,w));}}
计算log的方法可以提前用O(n)的预处理(方法2)或者每次lgn的计算(常数很小,基本上可以忽略)或者不知道常数的。。log算法
反正从代码上来看时间,log预处理计算
分别是1112ms 1224ms 1648ms
洛谷评测