NYOJ 119士兵殺敵(三)

2021-06-21 16:00:11 字數 1170 閱讀 8661

時間限制:

2000 ms  |  記憶體限制:

65535 kb

難度: 5

描述 南將軍統率著n個士兵,士兵分別編號為1~n,南將軍經常愛拿某一段編號內殺敵數最高的人與殺敵數最低的人進行比較,計算出兩個人的殺敵數差值,用這種方法一方面能鼓舞殺敵數高的人,另一方面也算是批評殺敵數低的人,起到了很好的效果。

所以,南將軍經常問軍師小工第i號士兵到第j號士兵中,殺敵數最高的人與殺敵數最低的人之間軍功差值是多少。

現在,請你寫乙個程式,幫小工回答南將軍每次的詢問吧。

注意,南將軍可能詢問很多次。

輸入只有一組測試資料

第一行是兩個整數n,q,其中n表示士兵的總數。q表示南將軍詢問的次數。(1

輸出對於每次詢問,輸出第m號士兵到第n號士兵之間所有士兵殺敵數的最大值與最小值的差。

樣例輸入

5 2

1 2 6 9 3

1 22 4

樣例輸出

1

7

這裡主要是rmq演算法:求一段區間範圍內的所有元素的最值。

maxnum[i][j](minnum[i][j])表示以點i位起點的長度為2^j的區間內的元素的最大(小)值。

查詢時k值的確定:因為在處理陣列maxnum[i][j]的時候,長度都是2^j(j=1,2,3...),然而題目給出的區間[start,end]長度length=end-start+1也許不能夠被2正除,所以要使查詢的速度盡可能快,我們應該選定乙個的k,它滿足下面的條件:2^k<=lenth;2^(k+1)>=lenth;這樣我們通過一次比較既可以得出給定區間內元素的最大值。

這樣求給定區間所有元素的最大值就轉換為求maxnum[x][k]與maxnum[y-(1<

#include#include#includeusing namespace std;

const int n=100000+5;

int maxnum[n][20],minnum[n][20];

void rmq(int n)

{ //注意下面的迴圈,j在外層,i在內層

//因為要求出以點i位起點的長度為2^j(j是遞增的)的區間內的元素的最值

for(int j=1;j<=20;j++)

for(int i=1;i<=n;i++)

{if(i+(1<

NYOJ119 士兵殺敵(三)

題目分析 這道題用的rmq演算法 range maximum minimum query 這裡做了幾點優化。1 定義dpmax和dpmin時,為什麼17寫在前面,因為記憶體中資料是按行連續的存的,所以初始化dpmax 0 和dpmin 0 相關資料時,可以直接用memcpy。2 所有的求2的方冪的操...

nyoj119士兵殺敵(三)

時間限制 2000 ms 記憶體限制 65535 kb 難度 5 描述 南將軍統率著n個士兵,士兵分別編號為1 n,南將軍經常愛拿某一段編號內殺敵數最高的人與殺敵數最低的人進行比較,計算出兩個人的殺敵數差值,用這種方法一方面能鼓舞殺敵數高的人,另一方面也算是批評殺敵數低的人,起到了很好的效果。所以,...

NYOJ 119 士兵殺敵(三)

士兵殺敵 三 時間限制 2000 ms 記憶體限制 65535 kb 難度 5 描述 南將軍統率著n個士兵,士兵分別編號為1 n,南將軍經常愛拿某一段編號內殺敵數最高的人與殺敵數最低的人進行比較,計算出兩個人的殺敵數差值,用這種方法一方面能鼓舞殺敵數高的人,另一方面也算是批評殺敵數低的人,起到了很好...