线段树应用和实现总结(持续更新)

应用情况

线段树非常通用,是基于分治思想的二叉树。区间查询问题一般都可以试试(一般没有没有单点查询的),有单点修改和区间修改。有些问题甚至可以离散化转换成区间问题。(待验证。)

值域线段树的重要误区

值域线段树以值本身作为下标,值的出现次数存在线段树里。值域线段树和普通的线段树的区别只是用例的使用方式的区别,而根据这种不同的应用方式才把这类线段树分类叫做值域线段树而已。因此线段树的内部实现丝毫不受影响。因此在开发值域线段树时一定封装,不受用例的使用方式的干扰,而时刻注意线段树提供的接口。

接口设计

  1. 添加和删除往往可以合并,只是正负的问题
  2. 询问全局的答案也就是询问root节点的答案

内部实现的总设计思路

既然是分治思想的线段树,查什么,保存什么(通常),再存一下分治合并时需要的信息即可。区间被完全覆盖的优化是时间复杂度的保证,因此思考查询与修改时区间被完全覆盖、和非完全覆盖合并时的两种情况如果更新,当然也可以考虑子节点(优先考虑叶节点)如何更新父节点。一定记住叶节点一定被完全覆盖。实现时一定铭记向下递归一定是有选择性的操作 。
综上:

  1. 查什么,保存什么。思考叶节点储存的信息
  2. 思考父节点如何由子节点更新而来,考虑额外的维护信息
  3. 考虑修改查询操作的完全覆盖和非完全覆盖(深知叶节点一定被覆盖)

具体实现

  1. 建树。常常我们会对一个区间建树。
//这是扫描线的代码
    void build(int u, int e, int o)
    {
        l[u]=e; r[u]=o; //左右端点赋值
        if(e==o-1) return; //判叶节点
        umid; //向下递归
        build(ul, e, mid);
        build(ur, mid, r);
    }
  1. 区间操作:判断操作区间与当前节点区间的包含关系:完全覆盖,非完全覆盖(传标记,左右选择递归,合并更新)
//这是扫描线的代码
    void modi(int u, int e, int o, int d)
    {
        //既然是分治的线段树结构 ,查什么,保存什么。
        //区间被完全覆盖的优化是时间复杂度的保证。
        //一定是有选择性的操作 
        if(e<=l[u]&&r[u]<=o) times[u]+=d; //被覆盖
        else //没被覆盖,讨论下递归
        {
            umid;
            if(e<=mid) modi(ul, e, mid, d);
            if(o>mid) modi(ur,  mid, r, d);
        } 
                //合并更新
        if(times[u]) width[u] = raw[r[u]] - raw[l[u]];
        else width[u] = width[ul] + width[ur];
    }
//这是区间求和的板子,
    int query(int p, int e, int o)
    {
        if(e<=l[p]&&r[p]<=o) //先判断完全覆盖
            return sum[p];
                //非完全覆盖
        spread(p); //有标记时先下传,选择性的合并
        pmid;
        int ans = 0;
        if(e<=mid) ans+= query(pl, e, o);
        if(o>mid) ans+= query(pr,e,o);
        return ans;
    }
  1. 单点修改:叶节点直接修改更新,其他节点选一边递归下去再合并更新。

各种不同维护信息的例题模板

  1. 区间乘加,区间求和
  2. 区间并
  3. 求区间最值

下面还有亟待解决的更难问题,也代表了即将学习平衡树和树套树。

曾老的OJ上有许多例题。

  1. 单点修改,区间第k小
  2. 索引单点插入,求最终队列

灵活多变的线段树

实际上线段树非常灵活:可以维护离散的序列,也可以维护真正的一维几何区间(例如扫描线)。

空间限制

可以动态开点和线段树合并,势能分析可得总体复杂度是线性对数的。
也可以离散化(貌似就不能在线了)。

正在更新

带着走还是储存边界?

如果没有初值,那就懒得建树,那我就直接带着走算了

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,711评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,079评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,194评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,089评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,197评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,306评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,338评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,119评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,541评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,846评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,014评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,694评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,322评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,026评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,257评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,863评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,895评论 2 351

推荐阅读更多精彩内容