zoukankan      html  css  js  c++  java
  • 【原创】线段树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

     
  • 相关阅读:
    Android 解决小米手机Android Studio安装app 报错的问题It is possible that this issue is resolved by uninstalling an existi
    Android Unresolved Dependencies
    Android studio 自定义打包apk名
    Android Fragment与Activity交互的几种方式
    魅族和三星Galaxy 5.0webView 问题Android Crash Report
    Android几种常见的多渠道(批量)打包方式介绍
    Android批量打包 如何一秒内打完几百个apk渠道包
    上周热点回顾(9.30-10.6)团队
    上周热点回顾(9.23-9.29)团队
    上周热点回顾(9.16-9.22)团队
  • 原文地址:https://www.cnblogs.com/liwenchi/p/5761257.html
Copyright © 2011-2022 走看看