A - Balanced Lineup

  题目:

题目网址:3264 -- Balanced Lineup (poj.org)

  思路:

用线段树来存储区间内的最大最最小值差异;

  代码实现:

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <math.h>
using namespace std;
int t,n,q;
long tree1[50010<<2];
long tree2[50010<<2];
long a[50010];
void PushUp(int rt){
    tree1[rt] =max(tree1[rt*2] , tree1[rt*2+1]) ; ///区间和的更新操作
    tree2[rt] =min(tree2[rt*2] , tree2[rt*2+1]) ;
}
 
void Build(int l,int r,int rt){
    // l,r 代表的是这个区间内的左端点和右端点,rt代表的是 [l,r] 这个区间内的值是存在哪一个位置的。
    if(l==r){
        //scanf("%d",&tree[rt]);
         tree1[rt] = a[l];
         tree2[rt] = a[l];
        return;
    }
    int m=(l+r)/2;// 对于区间区分,我们一般将m点划入左半边区间
    Build(l,m,rt*2);
    Build(m+1,r,rt*2+1);
    PushUp(rt); // PushUp 函数是通过2个子节点来更新现在这个节点的状态, 对于不同的要求需要不同的写法。
 
}
long MAXQuery(int l,int r,int rt,int L,int R){// [L,R]为查询区间
    if(L <= l && r <= R){
        return tree1[rt];// 如果成立则满足查询区间覆盖了当前区间, 直接返回当前区间的值
    }
    int m=(l+r)/2;
    long res=0;
    if(L<=m)    res=max(res,MAXQuery(l,m,rt*2,L,R));//左边有一部分需要查询的区域。
    if(m<R)     res=max(res,MAXQuery(m+1,r,rt*2+1,L,R));//右边有一部分。
    return res;
 
}
long MINQuery(int l,int r,int rt,int L,int R){// [L,R]为查询区间
    if(L <= l && r <= R){
        return tree2[rt];// 如果成立则满足查询区间覆盖了当前区间, 直接返回当前区间的值
    }
    int m=(l+r)/2;
    long res=0x3f3f3f;
    if(L<=m)    
res=min(res,MINQuery(l,m,rt*2,L,R));//左边有一部分需要查询的区域。 if(m<R)
res=min(res,MINQuery(m+1,r,rt*2+1,L,R));//右边有一部分。 return res; } int main() { scanf("%d%d",&n,&q); for(int i = 1; i <= n; i++) scanf("%ld", &a[i]); Build(1,n,1); int a,b; while(q--){ scanf("%d%d",&a,&b); cout << MAXQuery(1,n,1,a,b)-MINQuery(1,n,1,a,b) << endl; } return 0; }
posted @ 2021-08-04 15:27  wateriness  阅读(52)  评论(0)    收藏  举报