AOJ-351-求最值之差

Description
给出N个数,求第a个数到第b个数之间最大的数减去最小的数的结果

Input
N(N小于100,000),M(M小于100,000)
接下来有N个数
接下来M组范围,所有数均在[0,231-1]内
每个范围有2个整数a,b(1<=a<=b<=N)

Output
每行输出一个结果

Sample Input
5 3
4 2 5 1 10
1 5
2 3
2 2

Sample Output
9
3
0

—————————————————并不华丽的分界———————————————————————————————-

这题没什么好说的,线段树模板题。如果想要了解线段树,以及学习更多线段树,请戳http://blog.csdn.net/metalseed/article/details/8039326 里面详细的把线段树的单点更新和区间更新给介绍了一遍,嗯,还有很多例题。

#include <bits/stdc++.h>
using namespace std;
#define lson rt << 1
#define rson rt << 1 | 1

const int maxn = 100001;
struct panel
{
    int l, r;
    int big, small;
}tree[maxn << 2];
void build(int rt, int l, int r)
{
    tree[rt].l = l;
    tree[rt].r = r;
    tree[rt].big = 0;
    tree[rt].small = 0;

    if(l == r){
        scanf("%d",&tree[rt].big);
        tree[rt].small = tree[rt].big;
        return;
    }

    int mid  = (l + r) >> 1;
    build(lson, l, mid);
    build(rson, mid + 1, r);

    tree[rt].big = max(tree[lson].big, tree[rson].big);
    tree[rt].small = min(tree[lson].small, tree[rson].small);
}
int QueryMax(int rt, int l, int r)
{
    int mid = (tree[rt].l + tree[rt].r) >> 1;
    if(tree[rt].l == l && tree[rt].r == r)
        return tree[rt].big;
    else if(r <= mid)
        return QueryMax(lson, l, r);
    else if(l > mid)
        return QueryMax(rson, l, r);
    else
        return max(QueryMax(lson, l, mid),QueryMax(rson, mid + 1, r));
}
int QueryMin(int rt, int l, int r)
{
    int mid = (tree[rt].l + tree[rt].r) >> 1;
    if(tree[rt].l == l && tree[rt].r == r)
        return tree[rt].small;
    else if(r <= mid)
        return QueryMin(lson, l, r);
    else if(l > mid)
        return QueryMin(rson, l, r);
    else
        return min(QueryMin(lson, l, mid),QueryMin(rson, mid + 1, r));
}
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    build(1,1,n);
    for(int i = 0; i < m; i++)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        printf("%d
",QueryMax(1,a,b) - QueryMin(1,a,b));
    }
    return 0;
}
原文地址:https://www.cnblogs.com/wiklvrain/p/8179498.html