日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ST表讲解

發布時間:2023/12/3 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ST表讲解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

ST表主要用于解決RMQ問題(區間最值問題)
當然你可以用線段樹等,但今天用一種ST表(倍增算法)

ST表是倍增算法的一個典型應用
暴力做RMQ問題,往往會超時,ST表利用對其進行優化

給定一段序列A,ST算法能在O(NlogN)的時間預處理后,以O(1) 的復雜度查詢,在線回答在一段區間l,r 中最大(小)值是多少。

f[i][j]用于表示在序列a中, 從第i位數字往后數2j個數,這個區間內的最大值,即區間[ i , i + 2 j ]內取得的最大值。

而這段區域的最大值等于左右子區間的最大值,2j = 2 * 2 j-1 = 2j-1 + 2j-1,把區間[i,i+2j]分成[i , i + 2j-1 ] [ i + 2j-1 + 1,2j]
(即f [ i ] [ j - 1 ] 與 f [ i + 2 j-1 - 1 ] [ j -1 ] )

我們可得:F [ i ] [ j ] = max ( F [ i ] [ j - 1 ] , F [ i + 2 j-1 - 1 ] [ j - 1 ] )
遞推邊界為f[i][0]=a[i]

其實說白了就是:相求大區間就先求出小區間,求小區間就求小小區間,一直這樣套娃到最低層。

但是我們查詢的區間不一定總是2的倍數,也有可能會超出區間
所以我們詢問區間[l,r]時要用一個k,k=log2(len),len為區間的長度,k向下取整
len=r-l+1
2t<len<2t+1
左右區間最大值分別是F [ l , k ] 與F [ r - 2k + 1 , k ]

#include<cstdio> #include<iostream> #include<cmath>using namespace std;long f[100001][40]; int n,m;void ST()//預處理 {for(int k=1;k<=(int)log2(n);k++){for(int i=1;i<=n-(1<<k)+1;i++){f[i][k]=max(f[i][k-1],f[i+(1<<(k-1))][k-1]);}} } int query(int l,int r)//查詢 {int k=log2(r-l+1);return max(f[l][k],f[r-(1<<k)+1][k]);} int a[100]; int main(){cin>>n>>m;int temp;for(int i=1;i<=n;i++){scanf("%d",&a[i]);f[i][0]=a[i];}int l,r;for(int i=1;i<=m;i++){scanf("%d%d",&l,&r);cout<<query(l,r);}return 0; }

總結

以上是生活随笔為你收集整理的ST表讲解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。