最大最小值
时间限制:
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
-
首先输入一个整数T(T≤100),表示有T组数据。
这道题目用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));
}
}
}