POJ3264

题目链接:http://poj.org/problem?id=3264

保存区间内的最大值与最小值 然后做差

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>

using namespace std;

const int MAXN = 200001; // 区间范围
struct
{
    int l, r, m,n;  // l左断电 ,r右端点 ,m为该区间的最大分数,n为该区间的最大分数
} nod[MAXN*4];
int a[MAXN];

void creat(int t, int l, int r)
{
    nod[t].l = l, nod[t].r = r;
    if(l == r)       // 叶子节点
    {
        nod[t].m = a[l];
        nod[t].n = a[l];
        return;       //递归出口
    }
    int m = (l+r) / 2;
    creat(t*2, l, m), creat(t*2+1, m+1, r);     // 左孩子
    nod[t].m = max(nod[t*2].m, nod[t*2+1].m);   // 右孩子
    nod[t].n = min(nod[t<<1].n,nod[t<<1|1].n);
}
int query1(int t, int l, int r)                  // 查询t节点 在[l,r]区间范围的最大值
{
    if(l == nod[t].l && r == nod[t].r)
        return nod[t].m;
    int s;
    if(r <= nod[t*2].r)
        s = query1(t*2, l, r);
    else if(l >= nod[t*2+1].l)
        s= query1(t*2+1, l, r);
    else
        s = max(query1(t*2, l, nod[t*2].r), query1(t*2+1, nod[t*2+1].l, r));
    return s;
}
int query2(int t, int l, int r)                  // 查询t节点 在[l,r]区间范围的最小值
{
    if(l == nod[t].l && r == nod[t].r)
        return nod[t].n;
    int s;
    if(r <= nod[t*2].r)
        s = query2(t*2, l, r);
    else if(l >= nod[t*2+1].l)
        s= query2(t*2+1, l, r);
    else
      s = min(query2(t*2, l, nod[t*2].r), query2(t*2+1, nod[t*2+1].l, r));
    return s;
}
int main()
{
    int n, m, i, x1, x2;
    while(scanf("%d%d", &n, &m) != EOF)
    {
        for(i = 1; i <= n; i++) scanf("%d", &a[i]);
        creat(1, 1, n);     // 根节点标号为1,区间为[1,n]
        while(m--)
        {
            scanf("%d%d",&x1,&x2);
            printf("%d\n",query1(1,x1,x2)-query2(1,x1,x2));
        }
    }
    return 0;
}


你可能感兴趣的:(POJ3264)