洛谷 P3865 模板 ST表

2022-02-13 14:04:19 字數 1187 閱讀 9761

st表可以解決rmq問題,即區間最大值、最小值

速度快:預處理的時間複雜度是o(nlogn)。查詢的時間複雜度是o(1)。

不支援修改操作

st表借助於乙個陣列實現:st[i][j]表示從i為起點,2j個長度的區間最大值。

顯然,st[i][0]=a[i]; 即從i開始1個單位長度的最大值就是i。

然後是乙個雙層迴圈,第一層是列舉陣列的第二維下標,j從1開始(0已經預處理了),一直到log2(n),為什麼呢?因為第二維表示的是2j個長度單位,所以2log2(n)

<=n。

這裡可能對log2不理解,假設log2(n)返回的是k,那麼k是2k

<=n的最大整數。例如log2(4)=2  log2(5)=2  log2(6)=2  log2(7)=2  log2(8)=3 ……

所以說,j列舉到log2(n)就行了。

第二層迴圈列舉的是i,是第一維下標,從一開始,一直到i+(1我們推出狀態轉移方程:st[i][j]=max(st[i][j-1],st[i+(1<<(j-1))][j-1]);  //dp的思想,兩段的最大值就是整個區間的最大值。依舊不明白可以自己手推一遍試試。

為什麼要先迴圈j呢?因為我們初始化的是st[i][0],如果先迴圈i就會有一些分段還未求出。(建議大家手推一遍試試)

這樣,預處理就結束了。

每一次讀入要查詢的區間l--r,令k=log2(r-l+1).為什麼呢?r-l+1其實就是區間的長度。

令len=r-l+1,很顯然,len / 2 < 2log2(len)

<= len。所以說每一次輸出max(st[l][k],st[r-(1《在這裡st[i][k]一定越過了l--r區間的中點,st[r-(1附上**:

1 #include2 #include3 #include//

注意一定要用scanf和printf,否則會超時

4using

namespace

std;

5int n,m,a[200005],st[200005][35];6

intmain()

12for(int j=1;j<=log2(n);j++)16}

17for(int i=1;i<=m;i++)

23return0;

24 }

我建議大家感性理解一下,

要準確地證明真的比較難

。大家可以手算模擬一遍。

模板 ST表 洛谷P3865

題目背景 這是一道st表經典題 靜態區間最大值 請注意最大資料時限只有0.8s,資料強度不低,請務必保證你的每次查詢複雜度為 o 1 題目描述 給定乙個長度為 n 的數列,和 m 次詢問,求出每一次詢問的區間內數字的最大值。輸入輸出格式 輸入格式 第一行包含兩個整數 n,m 分別表示數列的長度和詢問...

模板 ST表(洛谷P3865)

給定乙個長度為 n 的數列,和 m 次詢問,求出每一次詢問的區間內數字的最大值。第一行包含兩個整數 n m 分別表示數列的長度和詢問的個數。第二行包含 個整數,記為 a i 依次表示數列的第 i 項。接下來 m 行,每行包含兩個整數 l i,r i 表示查詢的區間為 l i,r i 輸出包含 m 行...

ST表 (模板) 洛谷3865

題目背景 這是一道st表經典題 靜態區間最大值 請注意最大資料時限只有0.8s,資料強度不低,請務必保證你的每次查詢複雜度為 o 1 o 1 題目描述 給定乙個長度為 n n 的數列,和 m m 次詢問,求出每一次詢問的區間內數字的最大值。輸入輸出格式 輸入格式 第一行包含兩個整數 n,m n,m ...