题意
给定N个数(1 ≤ N ≤ 50,000),询问Q次(1 ≤ Q ≤ 200,000),每次询问某一区间[A,B]内的最大值和最小值的差。
样例
Sample Input
6 3
1
7
3
4
2
5
1 5
4 6
2 2
Sample Output
6
3
0
AC代码
#include<iostream>
#include<cstdio>
using namespace std;
int n,m,x,y;
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] = a[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 query(int x,int y)
{
int ansmax = a[y]; //该位置原树形数组的值
int ansmin = a[y];
while(x != y)
{
for(y-=1; y-lowbit(y) >= x; y -= lowbit(y))
{
ansmax = max(ansmax, maxVal[y]); //temp1[i]表示1-i区间中最大的值
ansmin = min(ansmin, minVal[y]);
}
ansmax = max(ansmax, a[y]);
ansmin = min(ansmin, a[y]);
}
return ansmax-ansmin;
}
int main()
{
//freopen("b.txt","r",stdin);
scanf("%d%d",&n,&m);
//cin>>n>>m;
init(n);
for (int i = 1; i <= m; i++)
{
scanf("%d%d",&x,&y);
//cin>>x>>y;
cout<<query(x,y)<<endl;
}
return 0;
}
题源:poj.org/problem?id=…