【POJ-3264】Balanced Lineup

63 阅读1分钟
题意

给定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=…