倍增:st表(模板)(洛谷P3865)
生活随笔
收集整理的這篇文章主要介紹了
倍增:st表(模板)(洛谷P3865)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
[傳送門](https://www.luogu.com.cn/problem/P38
解析
板子題最棒了
用mx[i][j]存儲以i為起點,長度為2^j次方的區間內的max
分成前后兩段,則可以得到遞推式:
而關于初始化,顯然:
mx[i][0]=a[i];預處理時間復雜度為nlogn
對于任意長度[l,r]
我們可以找到不大于其長度的最大的2^k
則max[l,r]=max(mx[l][k],mx[r - (1 << k) + 1][k])
畫圖大概就是這樣子滴:
(《神筆馬良》)
用兩段的最大值合并即整體的最大值
從而在O(1)的時間內完成單次詢問的查詢
問題解決
代碼
#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<iostream> #include<string> #include<queue> #include<vector> using namespace std; int n,m; int a[100500]; int mx[100500][17];//mx[i][j]:以i起點長度為2^j次方中的max int mi[20]; int q[100500]; void solve(){mi[0]=1;for(int i=1;i<=18;i++){mi[i]=mi[i-1] * 2;}int k=1;for(int i=1;i<=n;i++){if(mi[k]<=i) k++;q[i]=k-1;} } int main(){scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){scanf("%d",&a[i]);mx[i][0]=a[i];}solve();for(int k=1;mi[k]<=n;k++){for(int i=1;i+(1<<k)-1<=n;i++){mx[i][k]=max(mx[i][k-1],mx[i+mi[k-1]][k-1]);//printf("%d ",mx[i][k]);}//printf("\n");}for(int k=1;k<=m;k++){int st,ed;scanf("%d%d",&st,&ed);int j=q[ed-st+1];int ans=max(mx[st][j],mx[ed-mi[j]+1][j]);printf("%d\n",ans);}return 0; }AC快樂!!!
總結
以上是生活随笔為你收集整理的倍增:st表(模板)(洛谷P3865)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 二分:[BJWC2008]秦腾与教学评估
- 下一篇: 倍增:喷泉 深度解析(洛谷P7167)