ああ...
トピックリンク:https://www.luogu.com.cn/problem/P3865
アイデアの乗数を使用して、ST(スパース表)アルゴリズム、。
最小値の - 私たちは、区間[1 I、I + 2 ^ k]を表すF [i]が[K]の配列をみましょう。
明らかに再帰があります。
F [i]が[ 0 ] = [I]。 F [I] [J] = MAX(F [I] [J- 1 ]、F [I +(1 <<(J- 1))] [J- 1 ]。
クエリ:
区間[L、R]は、K = LOG2(R-L + 1)が得られます。次いで、[L] fを使用することができる[K]およびF [R-2 ^ J + 1] [j]を、すなわち最大答え= MAX(F [L] [K]、F [R-を与えるために、この範囲をカバーします(1 << J)+1] [K])
ACコード:
1の#include <cstdioを> 2の#include <cmath> 3の#include <iostreamの> 4 5 使用 名前空間STDを、 6 INT N、M。 7 のint A [ 100005 ]、ST [ 100500 ] [ 25 ]。 8 9 int型のmain(){ 10 のscanf(" %D%D "、&N、&M)。 11 のために(INT iは= 1 ; iが<= N; I ++){scanf関数(" %のD "、および[I])。ST [i]が[ 0 ] = [I];} 12 のために(INT J = 1 ; J <= LOG2(N); J ++ ){ 13 のために(INT iが= 1、I +(1 << J) - 1 <= N; I ++ ){ 14 ST [I] [J = MAX(ST [I] [J- 1 ]、ST [I +(1 <<(J- 1))] [J- 1 ])。 15 } 16 } 17 のために(INT iは= 1 ; iが<= M; I ++ ){ 18 のint L、R。 19 のscanf(" %D%D "、&L&R)。 20 INT K = LOG2(R-L + 1 )。 21 のprintf(" %D \ n "、MAX(ST [L] [K]、ST [R-(1 << K)+ 1 ] [K]))。 22 } 23 リターン 0 。 24 }