NYOJ 1185 最大最小值 (線段樹 & 區間最值查詢)

最大最小值

時間限制:1000 ms  |  內存限制:65535 KB
難度:2
描述
給出N個整數,執行M次詢問。
對於每次詢問,首先輸入三個整數C、L、R:

    如果C等於1,輸出第L個數到第R個數之間的最小值;

    如果C等於2,輸出第L個數到第R個數之間的最大值;

    如果C等於3,輸出第L個數到第R個數之間的最小值與最大值的和。

(包括第L個數和第R個數)。

輸入
首先輸入一個整數T(T≤100),表示有T組數據。
對於每組數據,先輸入一個整數N(1≤N≤10000),表示有N個整數;
接下來一行有N個整數a(1≤a≤10000);
然後輸入一個整數M,表示有M次詢問;
接下來有M行(1≤M≤10000),每行有3個整數C、L、R(1≤C≤3,1≤L≤R≤N)。
輸出
按照題意描述輸出。每個輸出佔一行。
樣例輸入
2
4
1 3 2 4
2
1 1 4
2 2 3
5
1 2 3 4 5
1
3 1 5
樣例輸出
1
3
6
題目鏈接:NYOJ 1185 最大最小值 (線段樹 & 區間最值查詢)

已AC代碼:

#include<cstdio>
#include<cstring>
#define M 10010

struct TREE{
	int left,right,max,min;
}tree[M*4];
int n,num[M];

int MAX(int x,int y)
{
	return x>y?x:y;
}
int MIN(int x,int y)
{
	return x<y?x:y;
}

int build_max(int l,int r,int root)
{
	tree[root].left=l;
	tree[root].right=r;
	if(l==r)
	{
		return tree[root].max=num[l];
	}
	int mid=(l+r)>>1;
	tree[root].max=MAX( build_max(l,mid,root<<1) , build_max(mid+1,r,root<<1|1) );
}

int build_min(int l,int r,int root)
{
	tree[root].left=l;
	tree[root].right=r;
	if(l==r)
	{
		return tree[root].min=num[l];
	}
	int mid=(l+r)>>1;
	tree[root].min=MIN( build_min(l,mid,root<<1) , build_min(mid+1,r,root<<1|1) );
}

int Query_max(int l,int r,int root)
{
	if(l<=tree[root].left && r>=tree[root].right)
	{
		return tree[root].max;
	}
	int mid=(tree[root].left+tree[root].right)>>1;
	if(r<=mid)
		return Query_max(l,r,root<<1);
	else if(l>mid)
		return Query_max(l,r,root<<1|1);
	else
		return MAX( Query_max(l,r,root<<1) , Query_max(l,r,root<<1|1) );
}

int Query_min(int l,int r,int root)
{
	if(l<=tree[root].left && r>=tree[root].right)
	{
		return tree[root].min;
	}
	int mid=(tree[root].left+tree[root].right)>>1;
	if(r<=mid)
		return Query_min(l,r,root<<1);
	else if(l>mid)
		return Query_min(l,r,root<<1|1);
	else
		return MIN( Query_min(l,r,root<<1) , Query_min(l,r,root<<1|1) );
}

int main()
{
	int T,m,i,c,l,r;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d",&n);
		for(i=1;i<=n;++i)
			scanf("%d",&num[i]);
		build_max(1,n,1);
		build_min(1,n,1);
		scanf("%d",&m);
		while(m--)
		{
			scanf("%d%d%d",&c,&l,&r);
			if(c==1)
				printf("%d\n",Query_min(l,r,1));
			else if(c==2)
				printf("%d\n",Query_max(l,r,1));
			else
				printf("%d\n", Query_min(l,r,1)+Query_max(l,r,1) );
		}
	}
	return 0;
}


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