[ NYOJ - 119] 士兵殺敵(三)(線段樹)

Link:點擊打開鏈接


士兵殺敵(三)

時間限制:2000 ms  |  內存限制:65535 KB
難度:5
描述

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

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

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

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

輸入
只有一組測試數據
第一行是兩個整數N,Q,其中N表示士兵的總數。Q表示南將軍詢問的次數。(1<N<=100000,1<Q<=1000000)
隨後的一行有N個整數Vi(0<=Vi<100000000),分別表示每個人的殺敵數。
再之後的Q行,每行有兩個正正數m,n,表示南將軍詢問的是第m號士兵到第n號士兵。
輸出
對於每次詢問,輸出第m號士兵到第n號士兵之間所有士兵殺敵數的最大值與最小值的差。
樣例輸入
5 2
1 2 6 9 3
1 2
2 4
樣例輸出
1
7


Code:


#include<stdio.h>
//#include<cstdlib>
//#include<cstring>
//#include<cmath>
//#include<iostream>
//#include<algorithm>
//#include<queue>
//#include<stack>     //去掉所有c++頭文件,改成c   否則會超時
using namespace std;
int MAX,MIN;
int max(int x,int y)  //c裏面沒有max,min函數 得重新定義
{
	if(x>y)
	return x;
	return y;
}
int min(int x,int y)
{
	if(x<y)
	return x;
	return y;
}
struct Tree
{
	int max,min;
}tree[1000010<<2];
void PushUp(int o)
{
	tree[o].max=max(tree[o<<1].max,tree[o<<1|1].max);
	tree[o].min=min(tree[o<<1].min,tree[o<<1|1].min);
}
void Build(int o,int l,int r)
{
	if(l==r)
	{
		int a;
		scanf("%d",&a);
		tree[o].max=tree[o].min=a;
		return;
	}
	int mid=(l+r)>>1;
	Build(o<<1,l,mid);
	Build(o<<1|1,mid+1,r);
	PushUp(o);
}
void Query(int o,int l,int r,int x,int y)
{
	if(l==x&&r==y)
	{
		MAX=max(tree[o].max,MAX);
		MIN=min(tree[o].min,MIN);
		return;
	}
	int mid=(l+r)>>1;
	if(y<=mid)
		Query(o<<1,l,mid,x,y);
	else if(x>mid)
		Query(o<<1|1,mid+1,r,x,y);
	else
	{
		Query(o<<1,l,mid,x,mid);
		Query(o<<1|1,mid+1,r,mid+1,y);
	}
}
int main()
{
	int N,M;
	scanf("%d%d",&N,&M);
	Build(1,1,N);
	while(M--)
	{
		int a,b;
		MAX=-100000010;
		MIN=100000010;
		scanf("%d%d",&a,&b);
		Query(1,1,N,a,b);
		printf("%d\n",MAX-MIN);
	}
return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章