zoukankan      html  css  js  c++  java
  • 线段树萌新讲解+一道水题【一点一滴】

    哈,线段树

    本来想这题就是很基础的,然后不想浅浅地讲解线段树,后来仔细想想,目前为止觉得嘛,线段树的操作就是在这个基础上转化啊转化~
    线段树的学习(挑战):
    所以很呆萌把在挑战书上的学习笔记摘过来,给巨巨们看看吧。。。

    1 基于线段树的RMQ的结构;

    在给定数列下,用O(logn)时间内实现①求区间最小值②修改某个位置的值
    处理:线段树每个节点维护对应区间的最小值。在建树时,只需要按从下到上的顺序分别取左右儿子的值中的最小值就好了。

    2 基于线段树的RMQ的查询;

    如果要求a0,…,a6的最小值。我们只需要三个节点的值的最小就可以了。(这个在挑战书上的图里,下面有思路)
    对于一个区间,我们去查询,线段树较上的节点对应较大的区间,通过这些区间就可以知道大部分的最小值,然后再去访问那些剩下的很少的节点就可以求得最小值了。
    具体步骤:
    1.如果要查询的区间和当前节点对应的区间完全没有交集,那么直接返回一个不影响答案的INF。
    2.如果所查询区间完全包含当前节点所对应的区间,那么就返回当前节点的值。
    3.以上两种情况都不满足,那只能说明:当前节点的区间完全包含了查询区间,或者说当前区间有些在被查询区间,有些不在查询区间。处理:对两个儿子进行递归处理,返回两个结果中的较小值。(这个处理自行画图会非常清楚)

    3 基于线段树的RMQ的值的更新

    在更新ai的过程中要让ai所在区间的对应的节点重新进行计算。
    处理:可以从下面向上不断进行更新。(就是递归(DFS)嘛,你一直在满足条件的过程中搜到最底,然后只要在返回中取个较小值就好了啊)。

    hdoj1754

    题意:

    思路:
    线段树两个基本操作,区间求最值,修改某个值并且更新。
    high一high线段树啦,很简单的啦~~~~哈哈哈哈哈哈哈哈哈哈哈哈

    #include<stdio.h>
    #include<string.h>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    const int INF=-0x3f3f3f3f;
    const int MAXN=200000;
    
    struct st{
        int left,right;
        int maxx;
    };
    st q[MAXN*4];
    int n,m;
    
    
    void built(int num,int L,int R)
    {
        q[num].left=L;
        q[num].right=R;
        if(q[num].left==q[num].right)
        {
            scanf("%d",&q[num].maxx);
            return;
        }
        built(2*num,L,(L+R)/2);
        built(2*num+1,(L+R)/2+1,R);
        q[num].maxx=max(q[2*num].maxx,q[2*num+1].maxx);
    }
    
    int get_maxa(int s,int t,int num)
    {
        if(s<=q[num].left&&t>=q[num].right)
            return q[num].maxx;
        if(s>q[num].right||t<q[num].left)
            return INF;
        int a,b;
        a=get_maxa(s,t,2*num);
        b=get_maxa(s,t,2*num+1);
        return max(a,b);
    }
    
    void update(int i,int x,int num)
    {
        if(q[num].left>i||q[num].right<i)
            return;
        if(q[num].left==i&&q[num].right==q[num].left)
        {
            q[num].maxx=x;
            return;
        }
        if(q[num].left<=i&&q[num].right>=i)
        {
            update(i,x,2*num);
            update(i,x,2*num+1);
            q[num].maxx=max(q[2*num].maxx,q[2*num+1].maxx);
        }
    }
    
    int main()
    {
        char ss[5];
        int x,y;
        while(~scanf("%d%d",&n,&m))
        {
            built(1,1,n);
            while(m--)
            {
                scanf("%s%d%d",&ss,&x,&y);
                if(strcmp(ss,"Q")==0)
                {
                    int ans=get_maxa(x,y,1);
                    printf("%d
    ",ans);
                }
                else
                {
                    update(x,y,1);
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    设计模式一:简单工厂模式
    排序算法一:冒泡排序
    设计模式三:工厂方法模式
    设计模式二:单例模式
    >Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause
    eclipse打开会出现初始化错误>解决办法
    easyui页面上的增删改功能
    springboot集成druid数据源
    springboot集成shiro的验证
    Java虚拟机
  • 原文地址:https://www.cnblogs.com/keyboarder-zsq/p/5934391.html
Copyright © 2011-2022 走看看