题目链接:[POJ 3264]Balanced Lineup[树状数组查询区间最大最小值]
题意分析:
查询每个区间的最大值与最小值之差。
解题思路:
用树状数组查询。具体见博文:[HDU 1754]I Hate It[树状数组查询+更新区间最大值]
只是多了个查询最小值。没啥区别。
个人感受:
对最大值最小值的查询还是没掌握牢固,多瞅瞅。
具体代码如下:
#include<iostream>
#include<cstdio>
using namespace std;
const int MAXN = 5e4 + 111;
int maxVal[MAXN], minVal[MAXN], a[MAXN];
int lowbit(int x)
{
return x & -x;
}
void init(int n)
{
for (int i = 1; i <= n; ++i)
{
scanf("%d", a + i);
maxVal[i] = minVal[i] = a[i];
for (int j = 1; j < lowbit(i); j <<= 1) // 与所有子区间比较
{
maxVal[i] = max(maxVal[i], maxVal[i - j]);
minVal[i] = min(minVal[i], minVal[i - j]);
}
}
}
int solve(int l, int r)
{
int retMin = a[r];
int retMax = a[r];
while (l != r)
{
for (r -= 1; r - lowbit(r) >= l; r -= lowbit(r)) // 1.判断此区间是否在查询范围内
{
retMax = max(retMax, maxVal[r]);
retMin = min(retMin, minVal[r]);
}
retMax = max(retMax, a[r]); // 2.如果不在查询范围内,则只能将第r个数单独加入判断
retMin = min(retMin, a[r]);
}
return retMax - retMin;
}
int main()
{
int n, m, a, b;
scanf("%d%d", &n, &m);
init(n);
while (m --)
{
scanf("%d%d", &a, &b);
printf("%d\n", solve(a, b));
}
return 0;
}