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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章