首页 > 其他分享 >线段树学习笔记

线段树学习笔记

时间:2023-06-13 15:55:32浏览次数:52  
标签:node 懒惰 线段 笔记 学习 二叉树 区间 ll

时隔多日,我终于又回来了!

这几天我学习几个高级数据结构,来和大家分享一下线段树。
线段树,名字好高级啊,是不是非常难学?我个人觉得吧,线段树只要明白原理,记熟模板,做题还是比较容易的。QwQ
OK,我们切入正题。

NO.1 what is 线段树

看图理解一下(图片还是比较形象的)

简单线段树结构图

这个东西就是个二叉树,它是一种特殊的二叉树,每个子节点都是一个区间,也可以近似的看做线段,so,他的名字就叫线段树了!
ok,了解完线段树的概念后,是不是会有疑问:它是干啥的?别急,接着看。

No.2 how to use 线段树

首先我们先不说去解决那些问题,我们先说说基础的。

(1)建立一棵线段树

树形结构要考虑如何建立以及存储这个结构,线段树也不例外。
因为是二叉树,所以建树方法肯定也不会太难,没错,看代码:

void build(int p,int l,int r)//其实就是建一棵二叉树
{
	lazy[p]=0;
	if (l==r)
	{
		tree[p]=a[l];
		return;
	}
	int mid=(r+l)>>1;
	build(p<<1,l,mid);
	build(p<<1|1,mid+1,r);
	tree[p]=tree[p<<1]+tree[p<<1|1];
}

当然建立的时候要考虑空间,因为这棵线段树可能不是满二叉树,空间却要补齐满二叉树,所以要开到叶子结点输得4倍(保险起见)。

(2)懒惰标记及其下放操作

相信大家看到上面建树的时候有一个lazy数组?这是做什么用的?
这就是懒惰标记,它在区间修改时会用到
线段树上区间修改时一个一个改肯定会超时,那怎么办,没错,就要用到懒惰标记。

举个形象点的例子,就是你过年时许多亲戚给你压岁钱,你父母帮你一个一个存着,然后你向父母询问的时候,他们就会把所有的钱给你(这例子是比较形象,就是不太现实)。
那我们肯定要下传懒惰标记,用代码如何实现,look this:

void push_down(ll node, ll st, ll ed) {
    if (lazy[node] == 0) {
        return;
    }

    ll l_node = node << 1;
    lazy[l_node] += lazy[node];
    tree[l_node] += lazy[node] * st;
    ll r_node = node << 1 | 1;//分别下传到左右两边子节点
    lazy[r_node] += lazy[node];
    tree[r_node] += lazy[node] * ed;
    lazy[node] = 0;
}

(3)单点修改

会了前两个,那我们来点实用性高的技巧,单点修改。
就是找到这个点,然后对它进行操作。
其实操作比较简单,以加法为例,代码如下:

void updata(ll node, ll l, ll r, ll pos, ll val) 
{
    if (l == r) 
    {
        a[pos] = val;
        tree[node] = val;
        return;
    }
    ll mid = (l + r) >> 1;
    if (pos <= mid) 
    {
        updata(node << 1, l, mid, pos, val);
    } 
    else
    {
        updata((node << 1) + 1, mid + 1, r, pos, val);
    }

    tree[node] = tree[node << 1] + tree[(node << 1) + 1];
}

(4)单点查询

就是直接二分查找就OK了
其实操作也比较简单,代码如下:

ll query(ll node, ll l, ll r, ll rl, ll rr) {
    if (rl <= l && r <= rr) {
        return tree[node];
    }

    ll res = 0;
    ll mid = (l + r) >> 1;

    if (rl <= mid) {
        res += query(node << 1, l, mid, rl, rr);
    }

    if (mid < rr) {
        res += query((node << 1) + 1, mid + 1, r, rl, rr);
    }

    return res;
}

(5)区间修改

这个时候就用到懒惰标记了。
据说懒惰标记这个东西的操作是线段树最精华的部分,懒惰标记下传后就是简单地修改了。
this is code:

void update(ll node,ll st,ll ed,ll l,ll r,ll val) 
{
    if (l<=st&&ed<=r) 
	{
        lazy[node]+=val;
        tree[node]+=val*(ed-st+1);
        return;
    }
    ll mid=(st+ed)>>1;
    push_down(node,mid-st+1,ed-mid);
    if (l<=mid) 
	{
        update(node<<1,st,mid,l,r,val);
    }
    if (r>mid)
	{
        update(node<<1|1,mid+1,ed,l,r,val);
    }
    tree[node]=tree[node<<1]+tree[node<<1|1];
}

(6)区间查询

这个一般是求区间的和,还是比较简单的。
求个和即可。
代码如下:

ll query(ll node,ll l,ll r,ll rl,ll rr)
{
    if(rl<=l&&r<=rr)
    {
        return tree[node];
    }
    ll res=0;
    ll mid=(l+r)>>1;
    if(rl<=mid)
    {
        res+=query(node<<1,l,mid,rl,rr);
    }
    if(mid<rr)
    {
        res+=query((node<<1)+1,mid+1,r,rl,rr);
    }
    return res;
}

No.3 practice

只说不做可不行,这里推荐几个题目以供大家练习。

1 P3374 【模板】树状数组 1

因为Luogu上板子题少,所以用树状数组的板子来练习线段树,内容是单点修改,区间查询。

2 P3368 【模板】树状数组 2

这道题的内容是区间修改,单点查询。

3 P3372 【模板】线段树 1

这道题的内容是区间修改,区间查询。

4 P3373 【模板】线段树 2

同样是区间修改,区间查询,但是不仅仅有加上一个数,又有乘一个数,考察懒惰标记如何下放。

标签:node,懒惰,线段,笔记,学习,二叉树,区间,ll
From: https://www.cnblogs.com/dhrwhy/p/16409569.html

相关文章

  • vue2 学习提纲
    手册慕课网-vue2手册:http://www.imooc.com/wiki/vuelesson/vueslot.html视频vue2.5入门https://www.imooc.com/learn/980echarts数据报表https://coding.imooc.com/learn/list/499.htmlVue+EChart4.0从0到1打造商业级数据报表项目vue2.6的版本2.快速入......
  • 「学习笔记」高斯消元
    简单说:高斯消元就是我们初中学的解方程组时用的加减消元法和代入消元法,只是高斯这个人最后总结了一下过程给定方程组\[\left\{\begin{aligned}3x+2y+z=10\quad&(1)\\5x+y+6z=25\quad&(2)\\2x+3y+4z=20\quad&(3)\\\end{aligned}\right.\]我们用......
  • 「学习笔记」严格次短路
    出题人说:“有最短路,还要有次短路。”于是,就有了次短路这个东西。与次小生成树一样,目前不知道有啥用。本文求的是严格次短路!变量n:点数;m:边数;e:vector存图;dis1:储存最短路;dis2:储存次短路。过程我们要利用dijkstra的贪心思想和松弛操作。dijkstra的贪心思想,就是用目前路......
  • mysql笔记
    1.mysql初始密码修改:进入mysql后,输入:ALTERUSERroot@localhostIDENTIFIEDBY'新密码';2.mysql打开命令:1.mysql-uroot-p,密码;2.mysql-uroot-p密码;3.显示所有数据库:showdatabases;;4.删除数据库:dropdatabase数据库名;;......
  • 强化学习驱动的低延迟视频传输
    随着视频会议、视频直播的流行以及未来AR/VR业务的发展,低延迟视频传输服务被广泛使用,但视频质量(QoE)还不能满足用户要求。那么近年来新兴的AI神经网络是否能为视频传输带来智能化的优化?今天LiveVideoStack大会北京站邀请了来自北京邮电大学的周安福教授,为我们分享关于使用强化学习方......
  • ​关于深度学习、NLP和计算机视觉的30个顶级Python库
    正文字数:2214 阅读时长:3分钟再次感谢艾哈迈德·阿尼斯(AhmedAnis)为收集这些数据做出的贡献,并感谢KDnuggets的其他工作人员的意见,见解和建议。作者/ MatthewMayo原文链接/https://www.kdnuggets.com/2020/11/top-python-libraries-deep-learning-natural-language-processing......
  • python入门笔记
     pip批量安装#安装和卸载pipwheel-wpackage_tmp_dir-rrequirement.txtpipdownload-dpackage_tmp_dir-rrequirement.txt#离线下载pipinstall-rrequirement.txtpipuninstallpackage#安装源:pipinstall-ihttps://pypi.douban.com/simple/package_name......
  • c++ linux基础学习第一课
    课程目标:1.shell命令解析器shell就是命令解析器,将用户命令翻译成内核能够识别的指令。shell常用的快捷键:tab:补齐命令,补齐文件(包括目录和文件)ctrl+a光标移动到头部,ctrl+e光标移动到尾部2.linux下主要目录:/bin保存着二进制文件、可执行程序和shell命令/sbins是superu......
  • 014 数据库学习笔记--查询
    常用查询方式:select*fromtablenameselectcol1,clo2fromtablenamewhereage=18selectcol1,clo2fromtablenamewhere age>=18andage<=60selectcol1,clo2fromtablenamewhere agebetween18and60selecttop(100)col1,clo2fromtablenamewhere ......
  • 如何使用机器学习提高推荐系统的准确性
    推荐系统是在互联网时代中非常重要的一项技术,它能够通过收集用户的行为数据和偏好,为用户提供个性化的推荐服务。而机器学习则是推荐系统中最为核心的部分,通过机器学习算法可以对大量的用户数据进行挖掘和分析,从而提高推荐系统的准确性和效率。下面,我将介绍一些如何使用机器学习提高......