時間限制:
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講解:解決本題有兩種方法,可以用線段樹,也可以用rmq演算法,rmq比較省時間,相對較優秀,7
其實線段樹也是比較常規的方法;
**如下:線段樹
1 #include2 #include3 #include4 #include5view codeusing
namespace
std;
6const
int maxx=100010;7
inta[maxx];
8int
big,small;
9struct
node
10tree[3*maxx];
14void build(int l,int r,int
v)15
24int mid=(l+r)>>1
;25 build(l,mid,v*2
);26 build(mid+1,r,v*2+1
);27 tree[v].max=max(tree[2*v].max,tree[2*v+1
].max);
28 tree[v].min=min(tree[2*v].min,tree[2*v+1
].min);29}
30void query(int a,int b,int
v)31
38int mid=(tree[v].left+tree[v].right)>>1;39
if(b<=mid) query(a,b,2*v);
40else
if(a>mid) query(a,b,2*v+1
);41
else
4246}47
intmain()
4861
return0;
62 }
rmq演算法:
1 #include 2 #include 3 #include 4 #include 5view codeusing
namespace
std;
6const
int n=100000;7
8int stmax[n][20],stmin[n][20],d[20];9
10void init(int
n)11
19int len = int(log(n*1.0)/log(2.0
));20
for(j=1;j<=len;j++)
21for(i=1;i<=n;i++)
22if(i+d[j]-1
<=n)
2327}28
void rmq(int q) //
2939}40
intmain()
NYOJ119 士兵殺敵(三)
題目分析 這道題用的rmq演算法 range maximum minimum query 這裡做了幾點優化。1 定義dpmax和dpmin時,為什麼17寫在前面,因為記憶體中資料是按行連續的存的,所以初始化dpmax 0 和dpmin 0 相關資料時,可以直接用memcpy。2 所有的求2的方冪的操...
NYOJ 119士兵殺敵(三)
時間限制 2000 ms 記憶體限制 65535 kb 難度 5 描述 南將軍統率著n個士兵,士兵分別編號為1 n,南將軍經常愛拿某一段編號內殺敵數最高的人與殺敵數最低的人進行比較,計算出兩個人的殺敵數差值,用這種方法一方面能鼓舞殺敵數高的人,另一方面也算是批評殺敵數低的人,起到了很好的效果。所以,...
nyoj119士兵殺敵(三)
時間限制 2000 ms 記憶體限制 65535 kb 難度 5 描述 南將軍統率著n個士兵,士兵分別編號為1 n,南將軍經常愛拿某一段編號內殺敵數最高的人與殺敵數最低的人進行比較,計算出兩個人的殺敵數差值,用這種方法一方面能鼓舞殺敵數高的人,另一方面也算是批評殺敵數低的人,起到了很好的效果。所以,...