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

這道題目用st算法或者線段樹就能解決,一個簡單的題,只要看懂線段樹與st算法就能解決。

#include <cstdio>
#include <algorithm>
#include <cmath>
//#define scanf scanf_s
using namespace std;
struct cd {
	int min;
	int max;
};
#define max_n 10005
cd sa[max_n][30];
int n;
void set()
{
	int i, j;
	for (j = 1; (1 << j) <= n; j++)
	{
		for (i = 0; i + (1 << j) - 1 < n; i++)
		{
			sa[i][j].max = max(sa[i][j - 1].max, sa[i + (1 << (j - 1))][j - 1].max);
			sa[i][j].min = min(sa[i][j - 1].min, sa[i + (1 << (j - 1))][j - 1].min);
			//cout << sa[i][j].min << " ";
		}
		//cout << endl;
	}
}
int get(int a, int b, int c)
{
	int j = (int)log2(c-b+1);
	int s = max(sa[b][j].max, sa[c - (1 << j) + 1][j].max);
	int k = min(sa[b][j].min, sa[c - (1 << j) + 1][j].min);
	if (a == 1)
		return k;
	else if (a == 2)
		return s;
	else
		return s + k;
}
int main()
{
	int i;
	scanf("%d",&i);
	while (i--)
	{
		int a;
		int b, c, d, s;
		scanf("%d",&n);
		for (a = 0; a < n; a++)
		{
			scanf("%d",&sa[a][0].min);
			sa[a][0].max = sa[a][0].min;
		}
		set();
		scanf("%d",&s);
		while (s--)
		{
			scanf("%d%d%d",&b,&c,&d);
			printf("%d\n",get(b,c-1,d-1));
		}
	}
}


發佈了68 篇原創文章 · 獲贊 14 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章