POJ3264——Balanced Lineup(线段树)

给你一个长度为n的序列a[N] (1 ≤ N ≤ 50000),询问Q(1 ≤ Q ≤ 200000) 次,每次输出[L, R]区间最大值与最小值的差是多少。
Input
多组用例
第一行是两个整数 N,Q
然后是N个数a[i] 保证a[i] 都小于1e9
然后是Q个询问 每次给你L,R 保证(1<=L<=R<= N)
Output
输出每次询问[L, R]区间最大值与最小值的差是多少.
#include <cstdio>  
#include <iostream>  
#include <cmath>  
#include <algorithm>  
#include <string>  
#include <cstring>  
// #define _ ios::sync_with_stdio(false) 
#define PI 3.141592653
using namespace std;
// #define rep(i,x,y) for(int i=x;i<y;i++)
const int INF = 10000000;
const int MAXN = 200050;
typedef long long ll;
int nMax,nMin;//记录最大最小值
struct Node
{
    int l,r;//区间的左右端点
    int nMin,nMax;//区间的最小值和最大值
}segTree[MAXN*3];
int a[MAXN];
void Build(int i,int l,int r)//在结点i上建立区间为(l,r)
{
    segTree[i].l=l;
    segTree[i].r=r;
    if(l==r)//叶子结点
    {
        segTree[i].nMin=segTree[i].nMax=a[l];
        return;
    }
    int mid=(l+r)>>1;
    Build(i<<1,l,mid);
    Build(i<<1|1,mid+1,r);
    segTree[i].nMin=min(segTree[i<<1].nMin,segTree[i<<1|1].nMin);
    segTree[i].nMax=max(segTree[i<<1].nMax,segTree[i<<1|1].nMax);
}
void Query(int i,int l,int r)//查询结点i上l~r的最大值和最小值
{
    if(segTree[i].nMax<=nMax&&segTree[i].nMin>=nMin)
        return ;
    if(segTree[i].l==l&&segTree[i].r==r)
    {
        nMax=max(segTree[i].nMax,nMax);
        nMin=min(segTree[i].nMin,nMin);
        return;
    }
    int mid=(segTree[i].l+segTree[i].r)>>1;
    if(r<=mid) Query(i<<1,l,r);
    else if(l>mid) Query(i<<1|1,l,r);
    else 
    {
        Query(i<<1,l,mid);
        Query(i<<1|1,mid+1,r);
    }
}
int main()
{
    int n,q;
    int l,r;
    int i;
    while(scanf("%d%d",&n,&q)!=EOF)
    {
        for(i=1;i<=n;i++)
            scanf("%d",&a[i]);
        Build(1,1,n);
        for(i=1;i<=q;i++)
        {
            scanf("%d%d",&l,&r);
            nMax=-INF;
            nMin=INF;
            Query(1,l,r);
            cout<<nMax-nMin<<endl;
        }
    }
    return 0;
}

 

posted @ 2017-07-07 16:22  饼饼饼饼饼  阅读(184)  评论(0编辑  收藏  举报