1270. 数列区间最大值
此题有多种方法做,线段树、树状数组、ST算法。这里我就用ST写个模板
ST算法 蓝书41页
给定一个长度为N的数组A,ST算法能在O(NlogN)时间复杂度预处理后,以O(1)的时间复杂度在线回答“数列A中下标在l-r之间的数最大值是多少”的这样区间最值问题。对于这一个问题,他比线段树快
模板
#include <iostream> #include <algorithm> #include <cmath> using namespace std; const int maxn = 1e5+10; int N,M; int arr[maxn],Log2[maxn];//原始数组,log2(x)数组 int f[maxn][20];//F[i][j]: arr[i~i+2^j-1]的最大值 void ST_init(){ //初始化所有长度为2^x的区间最大值 for(int i = 1;i<=N;i++) Log2[i] = log(i)/log(2); //初始化log求值,之后O(1)取值 for(int i = 1;i<=N;i++) f[i][0] = arr[i]; int len = log(N)/log(2) +1; for(int j = 1;j<len;j++){ for(int i = 1;i<=N-(1<<j)+1;i++){ f[i][j] = max(f[i][j-1],f[i+(1<<(j-1))][j-1]); } } } int query(int l,int r){ //查询arr[l~r]区间的最值 int k = Log2[r-l+1]; return max(f[l][k],f[r-(1<<k)+1][k]); } int main(){ cin>>N>>M; for(int i = 1;i<=N;i++) scanf("%d",&arr[i]); ST_init(); int x,y; while(M--){ scanf("%d%d",&x,&y); printf("%d\n",query(x,y)); } return 0; }