ST表

JiCanDuck發表於2024-08-30

ST表

定義

·也叫RMQ演算法
·給定序列,要求O(1)求區間(l,r)的最小值

·F[i][j]代表i到i+2^j-1的最小值。
·F[i][j]=min(f[i][j-1],f[i+2^(j-1)][j-1])
·O(nlogn)預處理

設k為最大的正整數滿足2^k<=r-l+1 Min(l,r)=min(f[l][k],f[r-2^k+1][k]) 如圖:

 

板子題

洛谷P3865 ST表

題目背景

這是一道 ST 表經典題——靜態區間最大值

請注意最大資料時限只有 0.8s,資料強度不低,請務必保證你的每次查詢複雜度為 O(1)O(1)O(1)。若使用更高時間複雜度演算法不保證能通過。

如果您認為您的程式碼時間複雜度正確但是 TLE,可以嘗試使用快速讀入:

inline int read()
{
	int x=0,f=1;char ch=getchar();
	while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
	while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
	return x*f;
}

函式返回值為讀入的第一個整數。

快速讀入作用僅為加快讀入,並非強制使用。

題目描述

給定一個長度為 NNN 的數列,和 M M M 次詢問,求出每一次詢問的區間內數字的最大值。

輸入格式

第一行包含兩個整數 N,MN,MN,M,分別表示數列的長度和詢問的個數。

第二行包含 NNN 個整數(記為 aia_iai​),依次表示數列的第 iii 項。

接下來 MMM 行,每行包含兩個整數 li,ril_i,r_ili​,ri​,表示查詢的區間為 [li,ri][l_i,r_i][li​,ri​]。

輸出格式

輸出包含 MMM 行,每行一個整數,依次表示每一次詢問的結果。

Code(

#include <bits/stdc++.h>
using namespace std;
const int MAXN=1e6+10;
inline int read()//快速讀入 
{
    char c=getchar();
	int x=0,f=1;
    while(c<'0'||c>'9'){
	if(c=='-')f=-1;
	c=getchar();
}
    while(c>='0'&&c<='9'){
		x=x*10+c-'0';c=getchar();
	}
    return x*f;
}
int Max[MAXN][21];
int st(int l,int r)//ST表 
{
    int k=log2(r-l+1); 
    return max(Max[l][k],Max[r-(1<<k)+1][k]);
}
int main(){
    int N=read(),M=read();
    for(int i=1;i<=N;i++) 
		Max[i][0]=read();
    for(int j=1;j<=21;j++)
        for(int i=1;i+(1<<j)-1<=N;i++)
            Max[i][j]=max(Max[i][j-1],Max[i+(1<<(j-1))][j-1]);
    for(int i=1;i<=M;i++)
    {
        int l=read(),r=read();
        printf("%d\n",st(l,r));
    }
    return 0;
}  

分析

題中時間限制只有800ms,時間複雜度尤為重要。
本蒟蒻最後兩個點就超時了
儘量使用快速讀入

人生忠告:

不要過於依賴cin cout 二者並不是萬金油,一些卡時間的題容易超時
printf YYDS

相關文章