数値の文字列を入力し、 MMクエリを実行します。各クエリでは、 X、Y、X 、Yの 2つの数値が表示さ れ、X XからY Yまでの 間隔の最大数を指定するよう求められます 。
入力
最初の行では、2つの整数 N 、M N、Mは桁数と問い合わせ数を表します。
次の行は N Nの数値です。
次の M M行では、各行に2つの整数 X 、Y X、 Y.
出力
出力は M M行で、各行は数値を出力します。
例
入力例
10 2
3 2 4 5 6 8 1 2 9 7
1 4
3 8
出力例
5
8
ヒント
すべてのデータのために、1 ≤ N ≤ 10 。5 、1 ≤ M ≤ 10 。6 、1 ≤ X- ≤ Y ≤ N 1≤N≤105,1≤M≤106,1≤X≤Y≤N。図は、超えない 範囲。C/C++
int
主な方法と複雑さは次のとおりです。
1.単純(つまり、検索)、O(n)-O(qn)オンライン。
2.
線分ツリー
、O(n)-O(qlogn)オンライン。
3、ST(本質において
動的プログラミング
)、O(nlogn)-O( オンラインQ)。
STアルゴリズム(スパーステーブル)、最大値を例にとると、d [i、j]は区間[i、i + 2 ^ j-1]の最大値を表し、区間[a、b]について尋ねられた場合答えの最大値はmax(d [a、k]、d [b-2 ^ k + 1、k])です。ここで、kは2 ^ k <= b-a + 1(つまり、長さ)を満たす最大の値です。 k、つまりk = [ln(b-a + 1)/ ln(2)]。
Dを求める方法であってもよい
動的プログラミング
、D [I、J] = MAX(D [I、J-1]、d [I + 2 ^(J-1)、J-1])。
4. RMQ標準アルゴリズム:最初に
LCA
(最下位共通祖先)に削減し、次にオンラインで制約付きRMQ、O(n)-O(q)に削減します。
まず、元によると
列の数
の設立
デカルト木
なので、問題はその
線形時間の
LCA問題の法律。LCA問題は、線形時間でRMQに削減できます。つまり、シーケンス内の任意の2つの隣接する数値間の差が+1または-1であるRMQ問題です。RMQ O(N)-O(1)溶液ラインの制約があるので、全体のアルゴリズムこと
時間複雑度は
O(N)-O(1)です 。
#include <bits / stdc ++。h> using namespace std; インラインint read(){ char ch = getchar(); int res = 0、f = 1 ; while(ch < ' 0 ' || ch> ' 9 '){ if(ch == ' - ')f = -1 ; ch = getchar();} while(ch> = ' 0 ' && ch <= ' 9 ')res = res * 10 + ch- ' 0 'getchar(); 解像度を返す * f; } inline void write(int zx){ if(zx < 0)zx = -zx、putchar(' - ' ); if(zx < 10)putchar(zx + ' 0 ' ); else { write(zx / 10 ); putchar(zx%10 + ' 0 ' ); } } int n、m、a [ 100010 ]、f [ 100010 ] [ 20]; void ST(){ for(int i = 1 ; i <= n; i ++)f [i] [ 0 ] = a [i]; 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 RMQ(int l、int r){ int k = 0 ; while((1 <<(k + 1))<= r-l + 1)k ++ ; max(f [l] [k]、f [r-(1 << k)+ 1 ] [k]);を返します。 } int main(){ n = read(); m = read(); for(int i = 1 ; i <= n; i ++)a [i] = read(); ST(); for(int i = 1 ; i <= m; i ++ ){ int l = read()、r = read(); 書き込み(RMQ(l、r)); putchar( ' \ n ' ); } 0を返し ます。 }