//ST表 //计算RMQ 即区间最值 //思想:区间dp+倍增 //注:将代码内所有max改成min即可求最小值 #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<algorithm> using namespace std; int n,m,l,r,a[100001]; int Pow[31],Log[100001];//Pow[i]表示2的i次幂 Log[i]表示log(i) int dp[100001][31];//dp[i][j]表示以i为左端点 长度为2^j-1的区间最值 void ST() { Pow[0]=1; for(int i=1;i<=30;i++) Pow[i]=Pow[i-1]*2; Log[0]=-1; for(int i=1;i<=100000;i++) Log[i]=log(i)/log(2); for(int i=1;i<=n;i++) dp[i][0]=a[i]; for(int j=1;j<=Log[n];j++) for(int i=1;i<=n-Pow[j]+1;i++) dp[i][j]=max(dp[i][j-1],dp[i+Pow[j-1]][j-1]); } void do_something() { for(int i=1;i<=m;i++) { scanf("%d%d",&l,&r); int p=Log[r-l+1]; printf("%d\n",max(dp[l][p],dp[r-Pow[p]+1][p])); } } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&a[i]); ST(); do_something(); return 0; }
原文地址:https://www.cnblogs.com/water-radish/p/9280521.html
时间: 2024-10-17 03:26:05