如果C等于1,输出第L个数到第R个数之间的最小值;
如果C等于2,输出第L个数到第R个数之间的最大值;
如果C等于3,输出第L个数到第R个数之间的最小值与最大值的和。
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
代码:
//区间线段树
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <math.h>
#include <algorithm>
using namespace std;
const int maxn= 10005;
int a[maxn];
int Min[maxn][20], Max[maxn][20];
int N; //元素个数
int read()
{
int res = 0, flag = 0;
char ch;
if((ch = getchar()) == '-') flag = 1;
else if(ch >= '0' && ch <= '9') res = ch - '0';
while((ch = getchar()) >= '0' && ch <= '9')
res = res * 10 + (ch - '0');
return flag ? -res : res;
}
int RMQ_Init() // 预处理出最大值和最小值
{
for(int i = 1; i <= N; i++)
Min[i][0] = Max[i][0] = a[i];
for(int j = 1; (1<<j) <= N; j++)
{
for(int i = 1; i + (1<<j) - 1 <= N; i++)
{
Min[i][j] = min(Min[i][j-1], Min[i + (1<<(j-1))][j-1]);
Max[i][j] = max(Max[i][j-1], Max[i + (1<<(j-1))][j-1]);
}
}
}
int RMQ_Min(int L, int R) // 查询[L,R]之间的最小值
{
int k = 0;
while((1<<(k+1)) <= R - L + 1) k++;
return min(Min[L][k], Min[R - (1<<k) + 1][k]);
}
int RMQ_Max(int L, int R) // 查询[L,R]之间的最大值
{
int k = 0;
while((1<<(k+1)) <= R - L + 1) k++;
return max(Max[L][k], Max[R - (1<<k) + 1][k]);
}
int main()
{
//freopen("1.txt","r",stdin);
//freopen("2.txt","w",stdout);
int T, M;
int C, L, R;
T=read();
while(T--)
{
N=read();
for(int i = 1; i <= N; i++) a[i]=read();
RMQ_Init();
M=read();
while(M--)
{
C=read();
L=read();
R=read();
if(C == 1) printf("%d\n", RMQ_Min(L, R));
else if(C == 2) printf("%d\n", RMQ_Max(L, R));
else printf("%d\n", RMQ_Max(L, R) + RMQ_Min(L, R));
}
}
return 0;
}
原文:http://blog.csdn.net/u013050857/article/details/45980003