poj3264

题目大意:给一列数,给一些询问,问[a,b]内最大值-最小值是多少

分析:比较简单的题目。以点建树,建树时,遇到叶子节点则读入,max = min = 读入值,否则用左右儿子的最大最小值来更新当前节点的最大最小值。查询就不多说了

很裸的线段树,一次ac
#include <iostream>
#include<stdio.h>
#include<cmath>
using namespace std;
const int MAX=50010;
int h[MAX],ma,mi;
typedef struct
{
    int left,right;
    int MAX,MIN;
}pe;
pe p[4*MAX];
void build(int k,int left,int right)
{
    p[k].left=left;
    p[k].right=right;
    if(left==right)
    {
        p[k].MAX=h[left];
        p[k].MIN=h[left];
        return;
    }
    int mid=(left+right)>>1,c1=k<<1,c2=c1+1;
    build(c1,left,mid);
    build(c2,mid+1,right);
    p[k].MAX=max(p[c1].MAX,p[c2].MAX);
    p[k].MIN=min(p[c1].MIN,p[c2].MIN);
}
void query(int k,int a,int b)
{
    if(p[k].left>b||p[k].right<a)
        return;
    int m1=p[k].MAX,m2=p[k].MIN;
    if(p[k].left>=a&&b>=p[k].right)
    {
        ma=max(m1,ma);
        mi=min(m2,mi);
        //cout<<k<<" "<<ma<<" "<<mi<<endl;
        return;
    }
    int mid=(p[k].left+p[k].right)>>1,c1=k<<1,c2=c1+1;
    {
        if(mid>=b)
        query(c1,a,b);
    else
        if(mid<a)
        query(c2,a,b);
    else
        if(mid>=a&&b>mid)
    {
        query(c1,a,mid);
        query(c2,mid+1,b);
    }
    }
}
int main()
{
    int N,Q,a,b;
    scanf("%d%d",&N,&Q);
    for(int i=1;i<=N;i++)
        scanf("%d",&h[i]);
    build(1,1,N);
    for(int i=0;i<Q;i++)
    {
        scanf("%d%d",&a,&b);
        ma=0;
        mi=1000010;
        query(1,a,b);
        printf("%d\n",ma-mi);
    }
    return 0;
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值