poj3264

来源:互联网 发布:质量管理体系数据分析 编辑:程序博客网 时间:2024/05/21 18:47

题目大意:给一列数,给一些询问,问[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;}
0 0
原创粉丝点击