ST表
阿新 • • 發佈:2020-07-18
ST表
ST表用來實現O(logn)預處理,O(1)查詢區間最值。
不支援修改
適用於O(logn)查詢區間最值會被卡的情況。
以查詢最大值為例。
預處理:記\(f_{i,k}\)表示從i開始\(2^k\)個數的最大值,則
\(f_{i,k}\)=max(\(f_{i,k}\),\(f_{i+2^{k-1}}\),k-1)。
查詢:設查詢區間[l,r],令p為滿足\(2^P\leq r-l+1\)的最大值,則答案為
max(\(f_{l,p}\),\(f_{r-2^P+1}\),p)。
用兩個長度為\(2^p\)的區間去覆蓋查詢區間,由於查詢區間的長度屬於[\(2^p,2^{p+1}\)),故一定能夠完整覆蓋
#include<iostream> #include<cstdio> #include<cmath> using namespace std; const int maxn=1e6+10; int m,n,l,r,k; int a[maxn][21]; inline int read() { int x=0,f=1;char ch=getchar(); while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();} while (isdigit(ch)){x=x*10+ch-48;ch=getchar();} return x*f; } int query(int l,int r) { int k=log2(r-l+1); return max(a[l][k],a[r-(1<<k)+1][k]); } int main() { n=read(),m=read(); for(int i=1;i<=n;i++) a[i][0]=read(); for(int j=1;j<=21;j++) for(int i=1;i+(1<<j)-1<=n;i++) a[i][j]=max(a[i][j-1],a[i+(1<<(j-1))][j-1]); for(int i=1;i<=m;i++) { l=read(),r=read(); printf("%d\n",query(l,r)); } return 0; }
題目推薦