Link: http://poj.org/problem? Id = 3264
Question: Give a string of numbers and ask for the difference between the maximum and minimum values of the interval.
Train of Thought: For rmq, we can use O (N ^ 2) preprocessing, and then each time we query O (1), we can use line segment tree and O (n) building, for O (logn) queries, you can use St table records, O (nlogn) preprocessing, and O (1) queries.
In fact, the St table preprocessing process is also a DP process. DP [I] [J] indicates the maximum range of 2 ^ J consecutive bits starting from the I bit.
Preprocessing: DP [I] [J] = min (DP [I] [J], DP [I + 2 ^ J] [J]), query: Query (L, r) = min (DP [l] [K], DP [R-2 ^ k + 1] [k]), k guarantees 2 ^ k <= r-L + 1 and 2 ^ (k + 1)> = r-L + 1.
Code:
# Include <iostream> # include <cstdio> # include <algorithm> # define maxn 50010 using namespace STD; int sttable_min [maxn] [32], sttable_max [maxn] [32]; int prelog2 [maxn], AA [maxn]; void st_prepare (int n, int * array) {prelog2 [1] = 0; For (INT I = 2; I <= N; I ++) {prelog2 [I] = prelog2 [I-1]; If (1 <prelog2 [I] + 1) = I) prelog2 [I] ++;} For (INT I = n-1; I> = 0; I --) {sttable_min [I] [0] = array [I]; sttable_max [I] [0] = array [I]; for (Int J = 1; (I + (1 <j)-1) <n; j ++) {sttable_min [I] [J] = min (sttable_min [I] [J-1], sttable_min [I + (1 <J-1)] [J-1]); sttable_max [I] [J] = max (sttable_max [I] [J-1], sttable_max [I + (1 <J-1)] [J-1]);} return ;} int query_sub (int l, int R) {int Len = r-L + 1, K = prelog2 [Len]; return max (sttable_max [l] [K], sttable_max [R-(1 <k) + 1] [k])-min (sttable_min [l] [K], sttable_min [R-(1 <K) + 1] [k]);} int main () {int N, Q; scanf ("% d", & N, & Q ); for (INT I = 0; I <n; I ++) scanf ("% d", & aa [I]); st_prepare (n, AA ); for (INT I = 0; I <q; I ++) {int L, R; scanf ("% d", & L, & R ); printf ("% d \ n", query_sub (L-1, R-1);} return 0 ;}