zoukankan      html  css  js  c++  java
  • 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(添加时记得备注)
  • 相关阅读:
    笔记 : windows系统下 命令行 php --version 的版本与phpinfo()版本不一致问题
    笔记 : WampServe加装PHP版本(7.2.3)为例
    Browsersync结合gulp和nodemon实现express全栈自动刷新
    PHP与JSP简单比较
    BDD 与DSL 入门
    1.display:flex布局笔记
    Css预处理器---Less(三)
    python_30期_第2讲【字符串&运算符】
    python_30期_第5讲【while循环+for循环】
    class_05py作业
  • 原文地址:https://www.cnblogs.com/bluefly-hrbust/p/10323675.html
Copyright © 2011-2022 走看看