セグメントツリーとフェンウィックツリー(RMQアルゴリズム)

兵士のキル(C)

制限時間: 2000のMS |メモリの制限:65535キロバイト
難易度: 5
説明

Nの兵士のコマンドで南の将軍、兵士たちは、1〜Nの番号が付された、南将軍は、多くの場合、キルの人々の最大の数の一定期間を取ることを愛し、キル二人の数の違いを比較して算出した人々の最小値を殺します値が、一方では、このようにinspireができますが、人々の数が多いを殺し、一方で非常に良い効果を果たし、低批判が人を殺すとみなすことができます。

だから、南将軍は、多くの場合、ほとんどの人々とあるメダルの敵の最小数の違いを、兵士へのストラテジストクーリー番号jのI兵士を尋ねる殺します。

さて、あなたは未熟練労働者南将軍は、すべてのクエリに答えるためにプログラムを書きます。

南将軍が何度も求めることができることに注意してください。

エントリー
試験データの一方のみセット
二つの整数Nは、兵士の総数を表すN、Q、の最初の行の。Qは尋ね南将軍の数を表します。(1 <N <= 100000,1 < Q <= 1000000)
Nの整数Viに(0 <= Viの<100000000の行に続いては )、 それぞれ皆を殺します。
再Qの行の後、各ラインは2つの正の正の数mを有し、nは、サザン一般問い合わせを表しているm番目のn番目の兵士の兵士へ。
輸出
クエリごとに、m番目の最大値と最小数の差のn番目の兵士の敵の兵士への出力との間のすべての兵士。
サンプル入力
5 2 
1 2 6 9 3 
1 2 
2 4
サンプル出力
1つの
7 
ソリューション:ツリーラインと、あなたもRMQアルゴリズムを使用することができ、私は非常に複雑に感じ、表示されませんでした。そこマクロ定義は、最高の資産計上。

思考:最大値と最小値:セグメントストレージノードは、2つの値を残し

#include <iostreamの> 
する#include <iostreamの> 
する#include <cstdioを> 
する#include < ストリング > 
の#include <CStringの> 
する#include <アルゴリズム> 
する#include <stdio.hに> 
する#include < 文字列・H>
 に#define担当者(I、 n)がため(INT i = 0; iが(N <); iは++)
 使用 名前空間STDを、
const  int型 N = 100009 ;
const  int型 INF = 0x3f3f3f3f 長い 長い ANS = 0、フラグ= 1 長いです 長い [ 200009 ]、SUM1 [ 200009 ]、SUM2 [ 200009 ]。
長い 長い MAX1 = -INF、MIN1 = INF。
構造体ノード{
     長い L、R、MI、MA。
}ツリー[N * 4 ]。

ボイドビルド(長い  L、長い 長い R、int型のルート)
{ 
    ツリー[ルート] .L = L、木[ルート] .R = R。
    もし(L == R)
    { 
        scanf関数(" %のLLD "、&ツリー[ルート]の.mi)。
        ツリー[ルート] .ma = ツリー[ルート]の.mi。
        返します
    } 
    長い 長い半ば=(L + R)>> 1 もし(L <= MID)
        ビルド(L、中間、ルート * 2 )。
    もし(R> 中旬)
        ビルド(ミッド + 1、R、根* 2 + 1 ); 
    ツリー[ルート]の.mi =分(ツリー[ルート* 2 ]の.mi、ツリー[ルート* 2 + 1 ]の.mi)。
    ツリー[ルート] .ma = MAX(木[ルート* 2] .ma、ツリー[ルート* 2 + 1 ] .ma)。
    COUT <<ツリー[ルート] .ma << "  " <<ツリー[ルート]の.mi << ENDL。
} 

ボイドクエリ(長い  L、長い 長い R、int型のルート)
{ 
    場合(ツリー[ルート] .L> = L &&ツリー[ルート] .R <= R)
    { 
        COUT <<ツリー[ルート] .ma << "  " <<ツリー[ルート]の.mi << てendl; 
        MAX1 = MAX(MAX1、ツリー[ルート] .ma)。
        MIN1 = 分(MIN1、
        返します
    } 
    長い 長い半ば=(ツリー[ルート] .L +ツリー[ルート] .R)>> 1 もし(L <= MID)
        クエリ(L、R、根 * 2 )。
    もし(R> MID)
        クエリ(L、R、根 * 2 + 1 )。
} 

int型のmain()
{ 

    int型N、Q。
    一方、(〜のscanf(" %d個の%のD "、&​​N&Q))
    { 
        構築(1、N 1 )。
        以下のためのINT I = 0、IはQを<; I ++は
        { 
            長い ロングL、R&LT; 
            scanfの(" %のLLDの%のLLD "、&​​L&R&LT)、
            クエリ(L、R&LT、1。); 
            COUT << MAX1 - MIN1 << endl; 
            MAX1 = -INF、MIN1 = INF; //はゼロああを割り当てることはできません。
        } 
    } 



    戻り 0 ; 
}

 

おすすめ

転載: www.cnblogs.com/nonames/p/11274899.html