#include <bits/stdc++.h>
#define MAX(x, y) (x>=y)?x:y
using namespace std; typedef long long LL; inline LL read(){ LL x=0; int f=1; char ch=getchar(); while(!isdigit(ch)) { if (ch=='-') f=-1; ch=getchar(); } while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch-48),ch=getchar(); return x*f; } int a[100001], f[100001][15]; int n, m; double t; void find(int x, int y){ double t=log(y-x+1)/log(2); int K=t; printf("%d\n", MAX(f[x][K],f[y-(1<<K)+1][K])); } signed main(){ n=read() ,m=read(); for (int i=1; i<=n; i++) f[i][0]=a[i]=read(); t=log(n)/log(2); int p=t; for (int j=1; j<=p; j++) for (int i=1; i+(1<<j)-1<=n; i++) f[i][j]=MAX(f[i][j-1], f[i+(1<<(j-1))][j-1]); for (int i=1; i<=m; i++){ int x=read(),y=read(); find(x, y); } return 0; }
ST表的功能很簡單html
它是解決RMQ問題(區間最值問題)的一種強有力的工具c++
它能夠作到O(nlogn)O(nlogn)預處理,O(1)O(1)查詢最值git
ST表是利用的是倍增的思想算法
拿最大值來講工具
咱們用Max[i][j]Max[i][j]表示,從ii位置開始的2^j2j個數中的最大值,例如Max[i][1]Max[i][1]表示的是ii位置和i+1i+1位置中兩個數的最大值spa
那麼轉移的時候咱們能夠把當前區間拆成兩個區間並分別取最大值(注意這裏的編號是從11開始的)code
這樣的話就能夠獲得x=r-2^k+1x=r−2k+1htm