LibreOJ-10119RMQ(範囲最小/最大クエリ)の問題

数値の文字列を入力し、  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(zx10 + ' 0 ' ); 
    } 
} 
int n、m、a [ 100010 ]、f [ 100010 ] [ 20];
void ST(){
     forint i = 1 ; i <= n; i ++)f [i] [ 0 ] = a [i];
    forint j = 1 ;(1 << j)<= n; j ++ ){
         forint 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();
    forint i = 1 ; i <= n; i ++)a [i] = read(); 
    ST(); forint i = 1 ; i <= m; i ++ ){
         int l = read()、r = read(); 
        書き込み(RMQ(l、r));

    
        putchar( ' \ n ' ); 
    } 
    0を返し ます
}

 

おすすめ

転載: www.cnblogs.com/xxxsans/p/12747662.html