-------------------------------------AlgorithmBrief Introduction ----------------------------------------- St algorithm O (nlogn) preprocessing, the maximum value of the specified range in O (1) query (take the minimum value as an example) Basically, we divide the interval to be evaluated [L, R] into two intervals with the length of Len. The left section is [l, l + len-1], and the right section is [R-len + 1, R] Len must overwrite the interval to be evaluated. Set the array to W. Then, the minimum value is the minimum value between the minimum values of the two intervals. Min (min {W [I], L <= I <= L + len-1}, min {W [J], r-len + 1 <= j <= r }) If the minimum values of the two intervals are obtained in advance The complexity of each query is O (1) --- Place a limit on Len: it can only be a power of 2 In the pre-processing, obtain the minimum values of all MI [B] [T]: ranges starting from B and growing to 2 ^ t. Then min (min {W [I], L <= I <= L + len-1}, min {W [J], r-len + 1 <= j <= r }) It becomes min (MI [l] [T], MI [R-2 ^ t + 1] [r]), where T can be obtained from, to ensure that the two intervals can overwrite the interval to be evaluated: T = ln (R-l + 1)/ln (2) --- We can see that MI [B] [T] = min (MI [B] [T-1], MI [B + 2 ^ (t-1)-1] [T-1]) Especially for all MI [I] [0], the value is W [I]; All MI [B] [T] The MI size is N * logn, the preprocessing time complexity is O (nlogn), and the query time complexity is O (1) -----------------------------------------------------Code------------------------------------------------------ Good response in poj Testing ~ I don't know how to direct the function pointer to any type of <operator. Only one "less than" function can be provided. Queries the minimum value of a specified interval. ---------------------------------- The following is the template ------------------------------------- Template <class type> Class rmq_st { PRIVATE: Type * body; Int ** Mi; Int size; Int Len; Int dint (double ){ Int Buf =; If (BUF> ){ -- Buf; } Return Buf; } Int mlen (int l, int R ){ Double Buf = Log (double) (R-l + 1)/log (double) 2 ); Return dint (BUF) } Bool (* Less) (type & T1, type & T2 ); Public: // Constructor: (array to be evaluated, size, smaller than the function) Rmq_st (type * con, int S, bool (* lessthan) (type & T1, type & T2 ));
~ Rmq_st (); // deconstruct
Type get_body (int p); // returns the element of the specified index. Int query_index (int l, int R); // returns the element index of the minimum value of the specified interval. Type query (int l, int R); // returns the minimum element of a specified range }; Template <class type> Rmq_st <type >:: rmq_st (type * con, int S, bool (* lessthan) (type & T1, type & T2 )){ Less = lessthan; Body = con; Size = s; Len = mlen (0, s-1) + 1; Mi = new int * [size]; Int I, J; For (I = 0; I <size; ++ I ){ Mi [I] = new int [Len]; } Int bound; Int A, B; For (I = 0; I <size; ++ I ){ Mi [I] [0] = I; } For (I = 1; I <Len; ++ I ){ Bound = N-(1 <I) + 1; For (j = 0; j <bound; ++ J ){ A = mi [J] [I-1]; B = mi [J + (1 <(I-1)] [I-1]; Mi [J] [I] = less (body [a], body [B])? A: B; } } } Template <class type> Rmq_st <type> ::~ Rmq_st (){ Int I; For (I = 0; I <size; ++ I ){ Delete [] MI [I]; } Delete [] Mi; } Template <class type> Type rmq_st <type >:: get_body (INT p ){ Return body [p]; } Template <class type> Int rmq_st <type >:: query_index (int l, int R ){ Int length = mlen (L, R ); Int A = mi [l] [length]; Int B = mi [R-(1 <length) + 1] [length]; Return less (body [a], body [B])? A: B; } Template <class type> Type rmq_st <type >:: query (int l, int R ){ Int length = mlen (L, R ); Int A = mi [l] [length]; Int B = mi [R-(1 <length) + 1] [length]; Return less (body [a], body [B])? Body [A]: Body [B]; } /* -------------- Example: poj 3264 memory: 7708 K time: 3230 Ms -----------------*/ Int cow [50001]; Int N, Q; Bool cmpmin (Int & T1, Int & T2 ){ Return t1 <t2; } Bool cmpmax (Int & T1, Int & T2 ){ Return T1> T2; } Int main () { // Freopen ("1.in"," r ", stdin ); Scanf ("% d", & N, & Q ); Int I; For (I = 0; I <n; ++ I ){ Scanf ("% d", & cow [I]); } Rmq_st <int> minst (cow, N, cmpmin ); Rmq_st <int> maxst (cow, N, cmpmax ); Int A, B; For (I = 0; I <q; ++ I ){ Scanf ("% d", & A, & B ); --; -- B; Printf ("% d \ n", maxst. Query (a, B)-minst. Query (a, B )); } Return 0; } |