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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

[学习笔记]ST表

發布時間:2025/7/25 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [学习笔记]ST表 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言:某次模擬賽T1被二維ST坑了。于是決心總結下。

?

ST表:O(常數)查詢靜態區間最值。

思想:利用倍增預處理。然后拼湊。

一維ST表:

f[i][j]表示,[i,i+(1<<j)-1]的區間最值。

lg[i]表示,log2i

#include<bits/stdc++.h> using namespace std; const int N=100000+10; int n,m; int a[N]; int f[N][30]; int lg[N]; int main() {scanf("%d%d",&n,&m);int t;for(int i=1;i<=n;i++) scanf("%d",&t),f[i][0]=t;for(int i=1;i<=n;i++) lg[i]=(i>>lg[i-1]+1)?lg[i-1]+1:lg[i-1];for(int j=1;(1<<j)<=n;j++)for(int i=1;(i+(1<<j)-1)<=n;i++){f[i][j]=max(f[i][j-1],f[i+(1<<j-1)][j-1]);}int l,r;for(int i=1;i<=m;i++){scanf("%d%d",&l,&r);int len=lg[r-l+1];printf("%d\n",max(f[l][len],f[r-(1<<len)+1][len]));}return 0; }

?

二維ST表:

類似處理二維前綴和。

先求出每行單獨的,然后再把行并起來。

f[i][j][k][l]表示,行[i,i+(1<<k)-1]與列[j,j+(1<<l)-1]圍成的矩形的數的最值。

lg[i]同上。

#include<bits/stdc++.h> #define ri register int #define numb (ch^'0') using namespace std; typedef long long ll; const int N=303; void rd(int &x){x=0;char ch;while(!isdigit(ch=getchar()));for(x=numb;isdigit(ch=getchar());x=(x<<1)+(x<<3)+numb); } int a[N][N]; int f[N][N][12][12]; int n,m,q; int lg[N]; inline int Max(const int &a,const int &b){return a>b?a:b; } int main(){scanf("%d%d",&n,&m);int now=1,id=0;for(ri i=1;i<=max(n,m);++i){if(i==now) lg[i]=id,now*=2,++id;else lg[i]=lg[i-1];}for(ri i=1;i<=n;++i){for(ri j=1;j<=m;++j){rd(a[i][j]);f[i][j][0][0]=a[i][j];}}for(ri l=1;l<=10;++l){for(ri i=1;i<=n;++i){for(ri j=1;j+(1<<l)-1<=m;++j){f[i][j][0][l]=Max(f[i][j][0][l-1],f[i][j+(1<<(l-1))][0][l-1]);}}}for(ri k=1;k<=10;++k){for(ri l=0;l<=10;++l)for(ri i=1;i+(1<<k)-1<=n;++i){for(ri j=1;j+(1<<l)-1<=m;++j){f[i][j][k][l]=Max(f[i][j][k-1][l],f[i+(1<<(k-1))][j][k-1][l]);}}}scanf("%d",&q);int x1,x2,y1,y2;while(q--){rd(x1);rd(y1);rd(x2);rd(y2);int l1=x2-x1+1;int l2=y2-y1+1;int g1=lg[l1],g2=lg[l2];//cout<<g1<<" "<<l1<<" "<<g2<<" "<<l2<<endl;int ans=0;ans=Max(ans,f[x1][y1][g1][g2]);//cout<<ans<<endl;ans=Max(ans,f[x1][y2-(1<<g2)+1][g1][g2]);//cout<<ans<<endl;ans=Max(ans,f[x2-(1<<g1)+1][y1][g1][g2]);//cout<<ans<<endl;ans=Max(ans,f[x2-(1<<g1)+1][y2-(1<<g2)+1][g1][g2]);printf("%d\n",ans);}return 0; }

?

?

樹上ST表

O(logn)查詢樹上兩點鏈之間的最值。logn因為要找LCA

處理方法類比倍增LCA。跳LCA的時候順便求出。

?

?

?

基于倍增思想的預處理。O(常數)查詢。

用于卡常數還是不錯的。

轉載于:https://www.cnblogs.com/Miracevin/p/9856967.html

總結

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

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