非递归线段树实现

news/2025/2/12 11:27:59/文章来源:https://www.cnblogs.com/cxjy0322/p/18579925

ZKW 非递归线段树

参考文章:线段树详解(非递归版)_非递归线段树-CSDN博客

建树:

原数组[1,n] 存在线段树的 [2,n+1] (为了方便区间查询,要空出第一个节点和最后一个节点)

区间查询

若查询[L,R] 区间, 选取L-1和 R+1 两个节点, 向上寻找.

  • 每次到达父节点 L-1 查看自己的父亲的右节点是否是R+1(或者自己是不是右节点),
    • 如果不是则加上右节点的 val .
  • R+1 节点则查看自己的父亲的左节点是否是 L-1(或者自己就是左节点),
    • 如果不是 加上左节点的 val .

线段树填充

若该线段树可维护 N 个元素

如果该线段树是满二叉树, 那么会有

​ 线段树下标 + N -1 = 存储下标

而之前为了方便区间查询有:

​ 原数组下标 + 1 = 线段树下标

那么如何确定 N 值?

​ N 是大于等于n +2 的,且由于要构造满二叉树, N 是 2 的幂次方

存在Lazytag 时该怎么进行区间查询?

​ 非递归是从下往上进行查询的

  • 如果题目允许, 可以先打上标记,所有标记都打完之后一次下推所有标记, 然后再开始查询

  • 如果标记和查询交错, 那么可以采用标记永久化的方法, 也就是不下推标记.

    L-1 与 R+1 节点往上查询的时候, 多带上一个变量, 记录此时已经计算了多少个数,当该节点达到了一个存在 tag标记的节点的时候, 加上tag 对各个数的影响,然后一次一路寻找到根节点, 返回答案

区间修改

#define maxn 100009
int a[maxn];
int sum[maxn<<2];//  区间和
int add[maxn<<2]; // 区间加lazytag
int n; // 原数组元素
int N: // N为扩充元素个数
#define ls(p)	(p<<1)
#define rs(p)	(p<<1|1)

建树

void build(int n){N =1 ;while(N<n+2)N<<=1;for(int i =1 ;i<=n;i++)sum[N+i] = a[i];// 直接修改叶子节点标记, 注意因为形成满二叉树, 其实有一些节点是空节点, 为0;for(int i= N -1 ;i>0;i--){// 更新根节点sum[i] = sum[ls(i)] + sum[rs(i)];add[i] = 0;}
}

点修改

void update(int l,int c){for(int i = N+l;i>0;i>>=1){sum[i] += c;}
}

区间修改(无tag, 单点修改版本)


void change(int l ,int r){l=l+N-1,r=r+N+1;// l^s^1 == 0 就代表 l 与 s 相邻, 也就是所有区间统计的内容都已经取完了int ans =0;while(l^s^1){if(~l&1) ans += sum[l^1]; //如果l 是左节点if(r&1)  ans += sum[r^1]; //如果r 是右节点l >>= 1;r >>= 1; 		// 寻找父亲节点}
}

注意l ^r ^1 = 0 除了存在相同的父节点还有一种情况,当然这两种情况都是可以直接退出的,可以所有打上的标记都已经统计完了:

图片1

区间修改(区间加版本)

void changeblock(int l,int r,int z){int i,j,s1=0,s2=0,x=0;for(i=l+N-1,j=r+N+1;i^j^1;i>>=1,j>>=1){sum[i] += s1 * z; sum[j] += s2 * z;if(~i&1) add[i^1] += z, sum[i^1]+= s1*z,s1+=x;// x 为包括的节点数if(j&1)  add[j^1] += z , sum[j^1]+=s2*z, s2+=x;}for(;i;i>>=1,j>>=1){// 更新上层sum[s] += s1* z;sum[t] += s2* z;}
}

区间查询(tag 版本, 区间加版本)

void query(int l,int r){int ans =0,i,j,s1,s2,x=1;for(i= l+ N-1,j = l+ N +1;i^j^1;i>>=1,j>>=1,x<<=1){if(add[i]) ans += s1*add[i];if(add[j]) ans += s2*add[j];if(~i&1) ans += sum[i^1],s1+=x;if(j&1)  ans += sum[j^1],s2+=x;}for(;i;i>>=1,j){if(add[i])ans+= s1 *add[i];if(add[j])ans++ s2 *add[j]}return ans ;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/844616.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

hot100-一刷-01哈希(共3道题)

1.两数之和 题目链接 题目描述代码实现 分析:暴力的话就是两个for循环依次寻找相加为target的两个数。 用一个map记录已经遍历过的数,其中key就用这个数的字面值,value就存它的下标。 判断是否相加为taget的时候,只需要看map中是否有target-nums[i]就可以,说明当前的nums[…

Activiti 学习笔记

工作流概述 每一项业务的开始和结束,都可以理解为一个工作流,例如,公司的费用报销的基本流程如下:员工先提出费用报销申请,提交给部门领导,部门领导审批后,提交给财务部门审批,审批完成后,通知提出申请的员工可以报销,报销流程结束。整个流程按照步骤完成,这就是一个…

高级程序语言设计课第九次作业

14.17.314.17.414.17.514.17.1014.17.1114.18.314.18.4 a: b: 14.18.5

WEB AK赛-web1_观字

对这段代码进行解析: substr($url, 0, 7) 截取url变量前7位判断是否是http协议 preg_match() 正则表达式检查 URL 中是否包含一些潜在的危险字符: 过滤了:., ;, |, <, >, *, %, ^, () 这题只需要绕过"."即可。 尝试使用url编码不可以 在curl中可以使用"…

Fail pg walkthrough Intermediate

nmap ┌──(root㉿kali)-[/home/ftpuserr] └─# nmap -p- -A 192.168.159.126 Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-12-01 02:54 UTC Nmap scan report for 192.168.159.126 Host is up (0.071s latency). Not shown: 65533 closed tcp ports (reset) PORT …

通过实现 FactoryBean 接口注入 Bean

原文:如何使用 Spring 的 FactoryBean 接口在 Spring 容器中有两类的 Bean,一类是普通的 Bean,一类是工厂 Bean。这两种 Bean 都是被 Spring 的容器进行管理的。而 Spring 也提供了一个接口用于扩展工厂 Bean,我们只要实现org.springframework.beans.factory.FactoryBean即…

探索古诺尔斯语:揭开维京时代语言的神秘面纱

在历史的长河中,有一些语言以其独特的文化和历史价值,成为语言学家、历史学家乃至文学爱好者研究的宝贵资源。古诺尔斯语,作为现代北欧语言的祖先,正是这样一个充满魅力的语言。它不仅是冰岛语、瑞典语、挪威语、丹麦语、法罗语和艾尔夫达利语的源头,更是维京时代斯堪的纳…

探索古英语的奥秘:一部语言的时光机

在历史的长河中,语言如同一条蜿蜒的河流,承载着文化的变迁和人类的智慧。古英语,作为英语的早期形式,不仅见证了中世纪英格兰的辉煌,更是现代英语的根基。它如同一部时光机,带我们穿梭回那个英雄与传说并存的时代,让我们得以窥见语言的原始面貌和文化的魅力。古英语:语…

【Altium Designer 25.0.2下载与安装教程】

1、安装包 「AltiumDesigner v25.0.2.28.rar」 链接:https://pan.quark.cn/s/babcbc39d4b1 提取码:EPis 2、安装教程(建议关闭杀毒软件和系统防护) 1) 下载并解压下载的安装包,右击Installer.exe安装,弹窗安装对话框2) 点击Next3) 选择语言Chinese,I…

字符串比较内容、模拟用户登录案例

1.equals、equalsIgnoreCase 在之前我们使用“==”比较的是字符串的地址,但是地址对于我们来说没有用,我们要比较的是字符串的内容。 而equals和equalsIgnoreCase就是用于比较字符串的内容的两种方法1.equals 比较两个对象的内容是否一致,如果一致则为true,否则为false 调用…

JVM学习-03-垃圾收集器与内存分配策略

第三章、垃圾收集器与内存分配策略3.1 概述 垃圾收集需要完成的三件事情:哪些内存需要回收? 什么时候回收? 如何回收?3.2 对象已死? GC相关博客:JVM GC?我比《深入理解Java虚拟机》再深入一点点_技术交流_牛客网 (nowcoder.com) 3.2.1 引用计数算法 在Java 领域,至少主…

20222323 2021-2022-2 《网络与系统攻防技术》实验七实验报告

1.实验内容 本实践的目标理解常用网络欺诈背后的原理,以提高防范意识,并提出具体防范方法。具体实践有 (1)简单应用SET工具建立冒名网站 (2)ettercap DNS spoof (3)结合应用两种技术,用DNS spoof引导特定访问到冒名网站。 2.实验过程 (1)简单应用SET工具建立冒名网站…