1 线段树,and树状数组 kennethsnow.

Slides:



Advertisements
Similar presentations
四川财经职业学院会计一系会计综合实训 目录 情境 1.1 企业认知 情境 1.3 日常经济业务核算 情境 1.4 产品成本核算 情境 1.5 编制报表前准备工作 情境 1.6 期末会计报表的编制 情境 1.2 建账.
Advertisements

主编:邓萌 【点按任意键进入】 【第六单元】 教育口语. 幼儿教师教育口 语概论 模块一 幼儿教师教育口语 分类训练 模块二 适应不同对象的教 育口语 模块三 《幼儿教师口语》编写组.
第一組 加減法 思澄、博軒、暐翔、寒菱. 大綱 1. 加減法本質 2. 迷思概念 3. 一 ~ 七冊分析 4. 教材特色.
海南医学院附 院妇产科教室 华少平 妊娠合并心脏病  概述  妊娠、分娩对心脏病的影响  心脏病对妊娠、分娩的影响  妊娠合病心脏病的种类  妊娠合并心脏病对胎儿的影响  诊断  防治.
植树节的由来 植树节的意义 各国的植树节 纪念中山先生 植树节的由来 历史发展到今天, “ 植树造林,绿化祖国 ” 的热潮漫卷 了中华大地。从沿海到内地,从城市到乡村,涌现了多少 造林模范,留下了多少感人的故事。婴儿出世,父母栽一 棵小白怕,盼望孩子和小树一样浴光吮露,茁壮成长;男 女成婚,新人双双植一株嫩柳,象征家庭美满,幸福久长;
客户协议书 填写样本和说明 河南省郑州市金水路 299 号浦发国际金融中 心 13 层 吉林钰鸿国创贵金属经营有 限公司.
浙江省县级公立医院改革与剖析 马 进 上海交通大学公共卫生学院
第二章 环境.
認識食品標示 東吳大學衛生保健組製作.
教师招聘考试 政策解读 讲师:卢建鹏
了解语文课程的基本理念,把握语文素养的构成要素。 把握语文教育的特点,特别是开放而有活力的语文课程的特点。
北台小学 构建和谐师生关系 做幸福教师 2012—2013上职工大会.
福榮街官立小學 我家孩子上小一.
第2期技職教育再造方案(草案) 教育部 101年12月12日 1 1.
企业员工心态管理培训 企业员工心态管理培训讲师:谭小琥.
历史人物的研究 ----曾国藩 组员: 乔立蓉 杜曜芳 杨慧 组长:马学思 杜志丹 史敦慧 王晶.
教育部高职高专英语类专业教学指导委员会 刘黛琳 山东 • 二○一一年八月
淡雅诗韵 七(12)班 第二组 蔡聿桐.
第七届全国英语专业院长/系主任高级论坛 汇报材料
小數怕長計, 高糖飲品要節制 瑪麗醫院營養師 張桂嫦.
制冷和空调设备运用与维修专业 全日制2+1中等职业技术专业.
会计信息分析与运用 —浙江古越龙山酒股份有限公司财务分析 组员:2006级工商企业管理专业 金国芳 叶乐慧 魏观红 徐挺挺 虞琴琴.
第六章 人体生命活动的调节 人体对外界环境的感知.
芹菜 英语051班 9号 黄秋迎 概论:芹菜是常用蔬菜之一,既可热炒,又能凉拌,深受人们喜爱。近年来诸多研究表明,这是一种具有很好药用价值的植物。 别名:旱芹、样芹菜、药芹、香芹、蒲芹 。 芹菜属于花,芽及茎类。
第二讲 职业概论.
颞下颌关节常见病.
电子商务企业创新分析 ——京东商城
致理科技大學保險金融管理系 實習月開幕暨頒獎典禮
蔬果的营养及卫生 赵 中.
Introduction 基本概念 授課老師:蕭志明
音乐中的数学之美 数学 张文博.
大连工业大学员工私家车保险 优惠方案 平安产险大连分公司 2011年1月 1.
主要内容 1. 利用估值对债券组合估价的优势 2. 如何评估债券估值的合理性 3. 产业债的定价与估值.
“法人代表”为员工投保操作手册 海康经代.
結腸直腸腫瘤的認知.
經歷復活的愛 約翰福音廿一1-23.
這真是默默的一群, 默默的表現著一個勞動者那種敦厚樸實的風範,她們的名字不會被人知道, 可是在我的心目中,她們是有資格被稱之為「人物」的一群。 那默默的一群 作者:張騰蛟.
大学英语教学在学分制教学的比重 类别 文科 理科 大学英语 《课程要求》 总学时 周学时 总学分
开题报告.
郭詩韻老師 (浸信會呂明才小學音樂科科主任)
技术试验及其方法 制作者 : 贾琼瑞
中国企业社会责任探讨 2010思政四组
计算机软件技术基础 数据结构与算法(4).
2. 戰後的經濟重建與復興 A. 經濟重建的步驟與措施 1.
好好學習 標點符號 (一) 保良局朱正賢小學上午校.
第8章 查找 数据结构(C++描述).
第四章 地理資訊與地理資訊系統.
禪宗的教外別傳.
4. 聯合國在解決國際衝突中扮演的角色 C. 聯合國解決國際衝突的個案研究.
新陸書局股份有限公司 發行 第十九章 稅捐稽徵法 稅務法規-理論與應用 楊葉承、宋秀玲編著 稅捐稽徵程序.
民法第四章:權利主體 法人 楊智傑.
第 1 章 演算法分析.
组员:张一凡 薛菲 马玉洁 提运亨 孙悦 顿凯 张刚 商明样 陈默
四年級 中 文 科.
Week 2: 程式設計概念與 演算法的效能評估
线段的有关计算.
聖誕禮物 歌羅西書 2:6-7.
新高中通識教育科教案設計分享會 現代中國: 中國文化與現代生活 朱秀玲老師.
数据结构选讲 北京大学 陈瑜希.
Assignment 8 #1 乔卓然
第1章 绪论(二) 教学目标 理解算法的特性及评价标准 掌握算法时间复杂度和空间复杂度的分析方法 1/
資料結構簡介 綠園.
3.16 枚举算法及其程序实现 ——数组的作用.
多层循环 Private Sub Command1_Click() Dim i As Integer, j As Integer
依撒意亞先知書 第一依撒意亞 公元前 740 – 700 (1 – 39 章) 天主是宇宙主宰,揀選以民立約,可惜他們犯罪遭
插入排序的正确性证明 以及各种改进方法.
第三章 流程控制 程序的运行流程 选择结构语句 循环结构语句 主讲:李祥 时间:2015年10月.
經文 : 創世紀一章1~2,26~28 創世紀二章7,三章6~9 主講 : 周淑慧牧師
本节内容 1. 平衡二叉树的定义 2.平衡化旋转 3.平衡二叉排序树的插入操作 昆山爱达人信息技术有限公司
慧能的教外別傳.
Presentation transcript:

1 线段树,and树状数组 kennethsnow

Problems with Intervals 区间查询 询问某段区间的某些性质(极值,求和,etc) 区间更新 某些操作影响了某段区间(统一加一个值……) 三个问题 更新点,查询区间 更新区间,查询点 更新区间,查询区间

一个使用了两年的经典问题 一个长度为N的一维数组(a[1]~a[N]) 我们每次对该数组有一些操作: 1、修改数组中某个元素的值 2、询问数组中某段区间的最大值 【1,5,4,1,6】---(max(1,4)=?)---> 5 3、询问数组中某段区间的和 【1,5,4,1,6】---(sum(3,5)=?)---> 11

线段树 如果只有一次询问? 线段树——在O(log2N)的时间内完成每次操作 O(Qlog2N) 枚举相应区间内的元素,输出答案 O(N) 更多的询问? Q次询问,O(NQ) That's too SLOW! 线段树——在O(log2N)的时间内完成每次操作 O(Qlog2N) Less than 1 seconds when N=Q=100000

线段树——结构 如何建树? 如何记录信息? 线段树的本质是一棵二叉树,不同于其它二叉树,线段树的每一个节点记录的是一段区间的信息。 e.g. 对于长度为5的数组a[1]~a[5] [1,5] [1,3] [4,5] [1,2] [3,3] [4,4] [5,5] [1,1] [2,2] 对于任一非叶子节点,若该区间为[L,R],则 左儿子为[L,(L+R)/2] 右儿子为[(L+R)/2+1,R] 如何建树? 如何记录信息?

数组[1,5,4,1,6] max=6 sum=17 [1,5] [1,3] [1,2] [3,3] [4,5] [5,5] [4,4] [2,2] [1,1] max=5 sum=10 max=6 sum=7 max=5 sum=6 max=4 sum=4 max=1 sum=1 max=6 sum=6 max=1 sum=1 max=5 sum=5

线段树——更新,a[2]=3 max=6 sum=14 max=6 sum=17 [1,5] [1,3] [1,2] [3,3] [4,5] [5,5] [4,4] [2,2] [1,1] max=4 sum=7 max=5 sum=10 max=6 sum=7 max=5 sum=6 max=3 sum=4 max=4 sum=4 max=1 sum=1 max=6 sum=6 max=1 sum=1 max=5 sum=5 max=3 sum=3

线段树——查询 sum(3,5)? ans=11 [1,5] [1,3] [1,2] [3,3] [4,5] [5,5] [4,4] [2,2] [1,1] ans=4 ans=7 ans=4

线段树——实现 每一个节点记录的信息? struct Tree { int left,right; //区间的端点 int max,sum; //视题目要求而定 }; 如何记录左儿子和右儿子?

线段树——实现(II) 一维数组即实现了线段树节点的保存 我们用一个数组a记录节点,且根节点的下标为1, 对于任一节点a[k], [1,5] [1,3] [1,2] [3,3] [4,5] [5,5] [4,4] [2,2] [1,1] 1 我们用一个数组a记录节点,且根节点的下标为1, 对于任一节点a[k], 它的左儿子为a[2*k] 它的右儿子为a[2*k+1] 2 3 5 4 7 6 一维数组即实现了线段树节点的保存 9 8

线段树——代码实现(建树) 建立一棵线段树,并记录原数组信息 如果原数组从a[1]~a[n],调用build(1,1,n)即可 void build(int id,int l,int r) { tree[id].left=l; tree[id].right=r; if (l==r) { tree[id].sum=tree[id*2].sum+tree[id*2+1].sum; tree[id].max=max(tree[id*2].max,tree[id*2+1].max; } else int mid=(l+r)/2; build(id*2,l,mid); build(id*2+1,mid+1,r); 如果原数组从a[1]~a[n],调用build(1,1,n)即可

线段树——代码实现(更新) 更新某个点的数值,并维护相关点的信息 若更新a[k]的值为val,调用update(1,k,val)即可 void update(int id,int pos,int val) { if (tree[id].left==tree[id].right) { tree[id].sum=tree[id].max=val; } else int mid=(tree[id].left+tree[id].right)/2; if (pos<=mid) update(id*2,pos,val); else update(id*2+1,pos,val); tree[id].sum=tree[id*2].sum+tree[id*2+1].sum; tree[id].max=max(tree[id*2].max,tree[id*2+1].max) 若更新a[k]的值为val,调用update(1,k,val)即可

线段树——代码实现(查询) 查询某区间内元素的和或最大值(以总和为例) 调用query(1,l,r)即可查询[l,r]区间内元素的总和 void query(int id,int l,int r) { if (tree[id].left==l&&tree[id].right==r) return tree[id].sum; //询问总和 else { int mid=(tree[id].left+tree[id].right)/2; if (r<=mid) return query(id*2,l,r); else if (l>mid) return query(id*2+1,l,r) return query(id*2,l,mid)+query(id*2+1,mid+1,r); } 调用query(1,l,r)即可查询[l,r]区间内元素的总和

线段树——时间复杂度 更新操作:由于总是一条路径从根到某个叶子,而树的深度为log2N,因而为O(log2N)

线段树——空间复杂度 设长度为N的数组在线段树中有F(N)个节点 因而对于2n<=N<=2(n+1),有 若N=2n, F(N)=2(n+1) 若N=2(n+1),F(N)=2(n+2) 因而对于2n<=N<=2(n+1),有 2(n+1)<=F(N)<=2(n+2) F(N)<=4*N

线段树——空间复杂度(II) 线段树空间应开为原数组长度的4倍 (图片转自http://comzyh.tk/blog/archives/479/) 线段树空间应开为原数组长度的4倍

线段树——小结 1、线段树可以做很多很多与区间有关的事情…… 2、空间复杂度~O(N*4),每次更新和查询操作的复杂度都是O(logN)。 3、在更新和查询区间[l,r]的时候,为了保证复杂度是严格的O(logN)必须在达到被[l,r]覆盖的区间的结点时就立即返回。而为了保证这样做的正确性,需要在这两个过程中做一些相关的“懒”操作。 “懒操作”在更新区间的有关问题上至关重要~

树状数组 一个一维数组tree[] 其中tree[i]表示 [i-(i&(-i))+1,i]这个区间内a数组元素的和 想求a[1]~a[15]的值? 15=(1111)2 tree[15]=sum[15,15] tree[14]=sum[13,14] tree[12]=sum[9,12] tree[8]=sum[1,8] sum[1,15]=tree[8]+tree[12]+tree[14]+tree[15] 执行的次数和二进制中‘1’的位数有关

树状数组——操作 read(int pos) 求 sum[1,pos]的答案 update(int pos,int v) 把a[pos]加上v 更新点查询区间 下标必须从1开始~ 如果要查询sum[l,r]呢? read(r)-read(l-1)

树状数组——代码实现 int read(int pos) { int ans=0; while (pos>0) ans+=tree[pos]; pos-=pos&-pos; } return ans;

树状数组——代码实现 void update(int pos,int val) { int ans=0; while (pos<=MAXN) //MAXN为总长度 tree[pos]+=val; pos+=pos&-pos; }

树状数组——代码实现 特殊应用:找整个数列的第K小数 int find_Kth(int k,int N) { int now=0; for (int i=20;i>=0;i--) now|=(1<<i); if (now>N || tree[now]>=k) now^=(1<<i); else k-=tree[now]; } return now+1;

树状数组——总结 1、树状数组可以更新点查询区间,也可以更新区间查询点,但一般不能更新区间查询区间。 2、单操作时间复杂度O(log2N),空间复杂度O(N). 3、代码简洁。 思考:1、如何实现树状数组更新区间查询点?(例如给某个区间统一加一个数,询问某点当前值) 2、修改tree数组的定义,使其能够实现更新某个点的值,并询问[1,pos]中的最大值。

线段树和树状数组比较 1、线段树可以做到的,树状数组不一定能,树状数组可以做到的,线段树一定能。 2、树状数组的常数明显小于线段树 3、线段树的代码量高于树状数组,但能解决的问题类型也多了很多。

线段树和树状数组进阶 将在下周继续……

26 Thank You! By kennethsnow