• 【原创】线段树query模板对比! 新手线段树的一个容易出错的问题!!因为我就糊涂了一整天.......


    我们解决问题的最好方法就是拿实例来举例子

    我们来看tyvj1038或计蒜客 “管家的忠诚”

    老管家是一个聪明能干的人。他为财主工作了整整10年,财主为了让自已账目更加清楚。要求管家每天记k次账,由于管家聪明能干,因而管家总是让财主十分满意。但是由于一些人的挑拨,财主还是对管家产生了怀疑。于是他决定用一种特别的方法来判断管家的忠诚,他把每次的账目按1,2,3…编号,然后不定时的问管家问题,问题是这样的:在a到b号账中最少的一笔是多少?为了让管家没时间作假他总是一次问多个问题。

    输入中第一行有两个数m,n表示有m(m< =100000)笔账,n表示有n个问题,n< =100000。 第二行为m个数,分别是账目的钱数 后面n行分别是n个问题,每行有2个数字说明开始结束的账目编号。

    输出文件中为每个问题的答案。具体查看样例。

     

    样例输入

    10 3
    1 2 3 4 5 6 7 8 9 10
    2 7
    3 9
    1 10
    

    样例输出

    2 3 1

    一道最最最基础的线段树的题,单点更新,求区间最小值,我们先来看两组代码,是两个不同的查询函数(query).

     
    1 struct nod
    2 {
    3     int l,r;
    4     int data;
    5 }tree[5*N];
     block 1:
    1
    int query(int i,int l,int r) 2 { 3 4 if(l<=tree[i].l&&tree[i].r<=r) 5 { 6 return tree[i].data; 7 } 8 int mid=(tree[i].l+tree[i].r)/2; 9 int ret = 99999999; 10 if(l<=mid) 11 ret = min(ret,query(i*2,l,r)); 12 if(r>mid) 13 ret = min(ret,query(i*2+1,l,r)); 14 return ret; 15 }
    来先看一下block 1 的10和12行,再对比一下block 2 的8和10行,是不是发现l和r反了呢?
    到底哪个是对的,哪个是错的?
     block 2:
    1
    int query(int i,int l,int r) 2 { 3 if(l<=tree[i].l&&tree[i].r<=r) 4 { 5 return tree[i].data; 6 } 7 int mid=(tree[i].l+tree[i].r)/2; 8 if(r<=mid) 9 return query(i*2,l,r); 10 if(l>mid) 11 return query(i*2+1,l,r); 12 return min(query(i*2,l,r),query(i*2+1,l,r)); 13 }

    我一开始学线段树的时候,也就是昨天...想找一个好一点的模板,但发现这两个模板好像不太一样,r和l完全是反的,尼玛!这肯定有一个是错的啊,这尼玛写错了不是误人子弟!!!幸好老夫多看了几个模板,要不然就被坑死了!!

    随着时间的推进,窝终于对线段树的理解越来越深,终于茅塞顿开!原来两个都是对的~~

    我现在来解析一下:

    block 2是我采用的类型,第8行的意思是如果你查询的右端都小于当前区间的mid了,那当前区间的data(视题目而定),肯定全部由左孩子过来的,直接返回左孩子的值,和右孩子没卵关系!第10行同理

    block 1是老师采用的类型,第10行的意思是只要你查询区间的左端小于当前区间的mid,那肯定有一部分是从左孩子来的,我先把你和ret比较一下,最小值记录到ret里,12行的意思,只要你查询区间的右端大于当前区间的mid,那肯定有一部分是从右孩子来的,我再把你和当前ret比较一下,最小值记录到ret里。最后我再输出ret。

    觉得怎么样呢,理解了没有?没有理解做一下这道题吧,理解会更深~

    附上我的题解http://www.cnblogs.com/liwenchi/p/5760660.html

     
  • 相关阅读:
    Python request
    Dockerfile详解
    k8s 英文文档翻译
    k8s 相关命令
    k8s 廖老师的分享
    Docker docker-compose安装
    Mysql 锁库与锁表
    Docker 二进制安装docker
    Java多线程的同步控制记录
    JAVA并行程序基础
  • 原文地址:https://www.cnblogs.com/liwenchi/p/5761257.html
Copyright © 2020-2023  润新知