#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int n,N,Q;
const int INT = 0x3f3f3f3f;
const int maxn = 1 << 16;
int dat_min[2*maxn-1], dat_max[2*maxn-1];
void update(int k, int ele) {
k += n-1;
dat_min[k] = ele;
dat_max[k] = ele;
while(k > 0)
{
k = (k-1)/2;
dat_min[k] = min(dat_min[2*k+1] , dat_min[2*k+2]);
dat_max[k] = max(dat_max[2*k+1] , dat_max[2*k+2]);
}
}
void init() {
n = 1;
while(n < N)
n *= 2;
for(int i = 0 ; i < 2*n - 1 ; i ++)
{
dat_min[i] = INT;
dat_max[i] = 0;
}
}
int query_for_min(int a , int b , int l , int r , int k) {
if(b <= l || a >= r)
return INT;
else if(a <= l && b >= r)
return dat_min[k];
else
{
int lchil = query_for_min(a,b,l,(l+r)/2 ,2*k+1);
int rchil = query_for_min(a,b,(l+r)/2,r,2*k+2);
return min(lchil,rchil);
}
}
int query_for_max(int a , int b , int l , int r , int k) {
if(b <= l || a >= r)
return -1;
else if(a <= l && b >= r)
return dat_max[k];
else
{
int lchil = query_for_max(a,b,l,(l+r)/2 ,2*k+1);
int rchil = query_for_max(a,b,(l+r)/2,r,2*k+2);
return max(lchil,rchil);
}
}
int main() {
while(scanf("%d%d",&N,&Q) != EOF)
{
init();
int tmp;
for(int i = 0 ; i < N ; i ++)
{
scanf("%d",&tmp);
update(i,tmp);
}
int fr,to;
for(int i = 0 ; i < Q ; i ++)
{
scanf("%d%d",&fr,&to);
int minimum = query_for_min(fr-1,to,0,n,0);
int maximum = query_for_max(fr-1,to,0,n,0);
printf("%d\n",maximum-minimum);
}
}
return 0;
}
poj 3264
/***************************/
/* poj 3264
*/
/*線段樹求解 RMQ 問題******/
/******Segment Tree********/
題目大意:
farmer
John 養了一羣奶牛,這些奶牛呢高度不一。有一天,farmer John 心血來潮,讓小牛們排隊玩極限飛碟。 他將奶牛們分成若干個Group,每個Group的奶牛排成一行。由於奶牛們的高度差會影響遊戲中的樂趣,因此farmerJohn 想知道,每一個Group中:第i個奶牛到第j個奶牛的範圍內,最高的奶牛比最矮的奶牛高多少?
思路:
問題可以轉化成求 數列下標 i~j 中最大的數與最小的數的差值。沒錯,這就是RMQ問題的變形。爲了提高程序運行的效率,使用線段樹求解RMQ問題。
ps:代碼所涉及到的區間默認都是 左閉右開的.
算法步驟:
一:初始化線段樹
二:分別用兩個數組 dat_min[] 和 dat_max[] 來存儲 區間 內的最大值和最小值。我們要求的就是 特定區間內的最大值-最小值.
三:輸出結果
算法複雜度:
一:N個最後一層節點初始化,每個節點更新的複雜度爲O(logN). --- O(NlogN)
二:2Q個詢問,每個詢問的複雜度爲O(logN). --- O(2QlogN)
由於Q的取值範圍比N大,則總的複雜度爲 --- O(QlogN)
運行結果:
Memory: 1376K
Time : 4141MS
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.