POJ

  这是线段树的一个模板题,给出一串数字,然后询问区间的最大最小值。

  这个其实很好办,只需把线段树的节点给出两个权值,一个是区间的最小值,一个是区间的最大值,初始化为负无穷和正无穷,然后通过不断地输入节点,不断维护,最好每次询问维护一个询问区间的最大值和最小值,最后相减即可。其实就相当于,线段树找区间的最大值和最小值。

  

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#define INF 0x3f3f3f3f
using namespace std;
int minv=INF;
int maxv=-INF;
struct node{
   int l,r;
   int minv,maxv;
   int mid()//中间值
   {
       return (l+r)/2;
   }
}tree[200010];
void buildtree(int root,int l,int r)
{
    tree[root].l=l;//区间左边
    tree[root].r=r;//区间右边
    tree[root].minv=INF;//区间内部的最小值
    tree[root].maxv=-INF;//区间内部的最大值
    if(l!=r)//不是根节点
    {
        buildtree(root*2+1,l,(l+r)/2);
        buildtree(root*2+2,(l+r)/2+1,r);
    }
}
void insert(int root,int i,int v){//单点修改
   if (tree[root].l==tree[root].r)
   {
       tree[root].r=i;
       tree[root].minv=tree[root].maxv=v;
       return;
   }
   tree[root].minv=min(tree[root].minv,v);//不是根节点,那么当插入的数不断往下更新时,需要不断对树上的节点范围内的最大值和最小值进行更新
   tree[root].maxv=max(tree[root].maxv,v);
   if(i<=tree[root].mid())
      insert(2*root+1,i,v);
   else
      insert(2*root+2,i,v);
}
void query(int root,int s,int e)
{
    if(tree[root].minv>minv && tree[root].maxv<maxv)//如果我前面维护的最小值已经比这一段的值还要小了,最大值也比这一段还要大了,那么无需再往下查询
        return ;
     if(tree[root].l==s && tree[root].r==e)//维护最大值和最小值
     {
         minv=min(minv,tree[root].minv);
         maxv=max(maxv,tree[root].maxv);
         return;
     }
     if(e<=tree[root].mid())//如过给出询问的区间不能通过一分为二分开,仍在区间的左边
        query(2*root+1,s,e);//仍然继续递归这个区间
     else if (s>tree[root].mid())
        query(2*root+2,s,e);//反之也继续递归这个区间
     else//需要把区间分开
     {
         query(2*root+1,s,tree[root].mid());//对半分
         query(2*root+2,tree[root].mid()+1,e);
     }
}
int main(){
  int n,q,h;
  scanf("%d%d",&n,&q);
  buildtree(0,1,n);
  for (int i=1;i<=n;i++){
    scanf("%d",&h);
    insert(0,i,h);
  }
  for (int i=0;i<q;i++)
  {
      int s,e;
      scanf("%d%d",&s,&e);
      minv=INF;
      maxv=-INF;
      query(0,s,e);
      printf("%d
",maxv-minv);
  }
  return 0;
}
有不懂欢迎咨询 QQ:1326487164(添加时记得备注)
原文地址:https://www.cnblogs.com/bluefly-hrbust/p/10323675.html