區間最大值,$o(nlogn)$ 預處理,$o(1)$ 查詢,不能動態修改。在查詢次數m顯著大於元素數量n的時候看得出差距。
令 $f[i][j]$ 表示 $[i,i+2^j-1]$ 的最大值。
顯然, $f[i][0]=a[i]$ 。
根據定義式,寫出狀態轉移方程: $f[i][j]=max(f[i][j-1],f[i+2^][j-1])$ 。
我們可以這麼理解:將區間 $[i,i+2^j-1]$ 分成相同的兩部分
中點即為 $(i+(i+2^j-1))/2=i+2^-1/2$
所以 $[i,i+2^j-1]$ 可以分成 $[i,i+2^-1]$ 和 $[i+2^j,i+2^j-1]$
對於每個詢問 $[x,y]$ ,我們把它分成兩部分 $f[x][s],f[y-2^s+1][s]$
其中 $s=log_2(y-x+1)$ ,雖然這兩個區間有重疊,但是重疊不會影響區間的最大值
#include usingnamespace
std;
#define ll long long
const
int maxlogn=17
;const
int maxn=100000
;int a[maxn+5],f[maxn+5][maxlogn+1],logn[maxn+5
];inline
intread()
while(c>='
0'&&c<='9'
)
return x*f;
}void
init()
}int
main()
return0;
}
二維:
#includeusingnamespace
std;
#define maxn 501
intn,m;
intrec[maxn][maxn];
char dp[maxn][maxn][11][11
];char dp1[maxn][maxn][11][11
];inline
int maxm(int a,int b,int c,int
d) inline
int minm(int a,int b,int c,int
d) void
st()
else
if(k==0
) else
if(l==0
) else
//printf("dp[%d][%d][%d][%d]=%d\n",i,j,k,l,dp[i][j][k][l]);}}
int rmq2dmax(int x,int y,int x1,int
y1)
int rmq2dmin(int x,int y,int x1,int
y1)
intmain()
}st();
for(int l=min(n,m); l; l--) }}
}}
資料結構 ST表
只遞推狀態空間在2的整數次冪位置上的值作為代表。當需要其他位置的值時,我們通過 任意整數可以表示成若干個2的次冪項的和 這一性質,使用之前求出的代表值拼出所需要的值。狀態空間關於2的次冪具有可劃分性 1 int power int a,int b,int p 2 10 return ans 11 快...
資料結構 ST表
倍增查詢表 區間查詢,單點多層次查詢,求lca 倍增思想,能夠快速向上推進查詢。void init intquery int a,int b lca模板 bzoj 1787 meet 緊急集合 description 歡樂島上有個非常好玩的遊戲,叫做 緊急集合 在島上分散有n個等待點,有n 1條道路...
st 表演算法模板
借鑑於 st表是基於二分的思想,st i j 表示j到j 2 n 1區間內的最值,長度為2 n 構建的時候用二分構建,那麼st i j 如何用其他狀態來繼承呢?j到j 2 i 1的長度為2 i,那麼一半的長度就等於2 i 1 那麼前半段的狀態表示為st i 1 j 後半段的長度也為2 i 1 起始位...