线段树初步理解...
来源:互联网 发布:手机以旧换新软件 编辑:程序博客网 时间:2024/06/05 20:29
原本这两天在搞网络流的....但最近几次网赛多次遇到了线段树的题目...意识到线段树还是重要的...所以今天就初步的了解了线段树最简单的应用...单点更新...今天学习线段树主要是看NotOnlySuccess大牛的模板(http://www.notonlysuccess.com/?p=978).代码风格非常好...很适合初学线段树的来参考...网上的一些PPT也不错...一步一步动态描述线段树的算法过程...
线段树是一棵二叉树...其根节点是整个区间...其叶子节点是单位区间...每次修改和查询的时间复杂度都是O(logn)...线段树的主要操作是
build ( 建树...其中这个地方我和队友讨论过是不是可以省去这一步..直接都先清0..然后按照插入的方式一个个插入...但自己研究了build部分的代码发现这一步尽量还是不要省...因为其建树时的速度比插入要快一些..)...其中参数sp是指的当前这个节点在二叉树中的编号...不难推出其左孩子为2*sp...右孩子为2*sp+1..开始我写的build是int类...然后最后是 return sum[sp]=build(l,Mid,sp*2) + build(Mid+1,r,sp*2+1); 但会出错...原因是输入数据不一定是2的阶乘..也就是这棵二叉树不一定时满的...所以这样赋值会调用到不要的空间..返回就会错误...
void build(int l,int r,int sp){ if (l==r) { scanf("%d",&sum[sp]); return ; } int Mid=(l+r)/2; build(l,Mid,sp*2); build(Mid+1,r,sp*2+1); sum[sp]=sum[sp*2]+sum[sp*2+1];}
..Insert(插入或者说更新单位区间的数据)..
void Insert(int k,int data,int l,int r,int sp){ if (l==r) { sum[sp]+=data; return ; } int Mid=(l+r)/2; if ( k<=Mid ) Insert(k,data,l,Mid,sp*2); else Insert(k,data,Mid+1,r,sp*2+1); sum[sp]=sum[sp*2]+sum[sp*2+1];}
Getsum( 得到一段区间的和或者是最大值之类的 )...
int GetAnwser(int L,int R,int l,int r,int sp){ if ( L<=l && R>=r) return sum[sp]; int Mid=(l+r)/2,ans=0; if ( L<=Mid ) ans+=GetAnwser(L,R,l,Mid,sp*2); if ( R> Mid ) ans+=GetAnwser(L,R,Mid+1,r,sp*2+1); return ans;}
当然这只是线段树的最简单应用...其实关于单点更新的题目...用树状数组应该编程复杂度会更低..效率也差不多...但这里先当做是线段树的一个入门吧...
- 线段树初步理解...
- 初步线段树 hdu1166
- 线段树初步
- 线段树初步
- 线段树初步__ZERO__.
- 线段树_初步
- hdu 1166 线段树 (初步)
- 线段树 初步:hdu 1166
- 线段树入门 理解
- 一步一步理解线段树
- 一步一步理解线段树
- 一步一步理解线段树
- 一步一步理解线段树
- 线段树入门理解
- leetcode -- 线段树理解
- 线段树入门理解
- 一步一步理解线段树
- 一步一步理解线段树
- inputtext(javascript,限制输入两位整数,不满两位前端自动补零)
- NDK Jni学习
- zoj 2532(Internship )找割边
- 简单的QT绘图程序
- 开始运行命令集合
- 线段树初步理解...
- WinCE全屏
- 日本語网站
- 你应该知道的 15个Linux Bash拓展例子
- Windows Server 2003 IIS配置经典
- 关于namespace
- JavaScript 消息框
- 结合工具来实现敏捷开发 - 12
- List的特殊操作