首页 > 其他分享 >线段树合并模板

线段树合并模板

时间:2024-08-09 11:06:13浏览次数:6  
标签:int 合并 线段 tr pos rc now Sum 模板

template<class Node>
struct PersidentSegmentTree {
#define lc(u) tr[u].l
#define rc(u) tr[u].r
    const int n;
    int tot = 0;
    vector<Node> tr;
    vector<int> root;

    PersidentSegmentTree(): n(0) {}

    PersidentSegmentTree(int n_): n(n_) {
        int N = (n << 6) + 10;
        tr.reserve(N); root.reserve(N);
        tr.resize(N); root.resize(N);
    }

    PersidentSegmentTree(vector<int>& a): PersidentSegmentTree(a.size() - 1) {
        function<void(int&, int, int)> build = [&](int& now, int l, int r) {
            now = ++ tot;
            if (l == r) {
                return ;
            }
            int m = (l + r) >> 1;
            build(lc(now), l, m);
            build(rc(now), m + 1, r);
        };
        build(root[0], 1, n);
    }

    //上传
    void pushup(int u) {
        if (tr[lc(u)].Sum >= tr[rc(u)].Sum) {
            tr[u].Sum = tr[lc(u)].Sum;
            tr[u].pos = tr[lc(u)].pos;
        } else {
            tr[u].Sum = tr[rc(u)].Sum;
            tr[u].pos = tr[rc(u)].pos;
        }
    }

    //动态开点/更新树结点
    void insert(int& now, int l, int r, int pos, int w) {
        if (!now)
            now = ++ tot;

        if (l == r) {
            tr[now].Sum += w;
            tr[now].pos = pos;
            return;
        }

        int m = l + r >> 1;
        if (pos <= m)
            insert(lc(now), l, m, pos, w);
        else
            insert(rc(now), m + 1, r, pos, w);
        pushup(now);
    }

    //开新前缀树,last代表前缀,now代表新树根
    void insert(int& now, int last, int l, int r, int pos, int w) {
        now = ++ tot;
        tr[now] = tr[last];
        if (l == r) {
            return;
        }
        int m = l + r >> 1;
        if (pos <= m)
            insert(lc(now), lc(last), l, m, pos, w);
        else
            insert(rc(now), rc(last), m + 1, r, pos, w);
    }

    //单点
    int query(int now, int l, int r, int pos) {
        if (l == r) {
            return tr[now].Sum;
        }

        int m = l + r >> 1;
        if (pos <= m)
            return query(lc(now), l, m, pos);
        else
            return query(rc(now), m + 1, r, pos);
    }

    //区间查询 [u,v]->[root[l-1],root[r]]
    int query(int u, int v, int l, int r, int pos) {
        if (l == r) {
            return tr[u].Sum;
        }

        int m = l + r >> 1;
        if (pos <= m)
            return query(lc(u), lc(v), l, m, pos);
        else
            return query(rc(u), rc(v), m + 1, r, pos);
    }

    void merge(int &u, int v, int l, int r) {
        if (!u || !v) {
            u = u + v;
            return;
        }

        if (l == r) {
            tr[u].Sum += tr[v].Sum;
            return ;
        }

        int m = l + r >> 1;
        merge(lc(u), lc(v), l, m);
        merge(rc(u), rc(v), m + 1, r);
        pushup(u);
    }
};

struct Node {
    int l, r;
    int Sum = 0, pos = 0;
};

标签:int,合并,线段,tr,pos,rc,now,Sum,模板
From: https://www.cnblogs.com/Kescholar/p/18350415

相关文章

  • C++标准模板库(STL)|容器|vector| queue|
    对STL进行总结,STL是standardtemplatelibrary的简写,是C++中的一个标准模板库,用于实现常用的数据结构和算法,它是C++程序员经常使用的一个工具箱。STL的主要目的是提高开发效率和代码质量,使得程序员可以更加便捷地完成常见的操作。里面包括:算法(algorithm)、容器(container)、仿函......
  • 大质数分解模板
    jiangly的(偷一下i64mul(i64a,i64b,i64m){returnstatic_cast<__int128>(a)*b%m;}i64power(i64a,i64b,i64m){i64res=1%m;for(;b;b>>=1,a=mul(a,a,m))if(b&1)res=mul(res,a,m);......
  • C# 设计模式之模板方法模式
    总目录前言在日常的工作中,有时候我们做PPT,做合同,做简历,如果我们自己从头去写这些文档,不免有些太过耗时耗力;大多时候都是去找相关的PPT模板,合同模板,简历模板,拿过来直接用。为什么可以使用模板,因此这些资料大部分的信息和信息框架都是一致的,我们只需要将自己差异化的内容填......
  • 将二维数组与一维数组合并
    我目前np.append与两个数组组合,但它不能工作,它显示:ValueError:alltheinputarraydimensionsexceptfortheconcatenationaxismustmatchexactly,butalongdimension0,thearrayatindex0hassize64andthearrayatindex1hassize0这是我的......
  • 黑神画Ⅱ--Unix 是下一代人工智能的模板吗?
    有一张图被用来描述GPT5比GPT4大多少,GPT3被描绘成一条大白鲨,GPT4被描绘成一条虎鲸,然后GPT5被描绘成一条座头鲸,这表明它们训练的数据量大幅增加。这是一个有趣的类比,因为它传达了规模的概念,但当你思考这些类比代表什么时,它就更加有趣了。GPT3是鱼类世界中的顶级捕食......
  • 创造智能对话:在LangChain中巧妙使用变量与模板
    创造智能对话:在LangChain中巧妙使用变量与模板在人工智能的世界里,对话管理是一项艺术,也是一项技术挑战。LangChain作为一个前沿的对话管理框架,提供了一套强大的工具,让开发者能够创建动态、个性化的对话体验。本文将深入探讨如何在LangChain中创建和管理变量,通过详细的步骤......
  • Git合并之————指定提交记录合并
    应用场景在测试环境提交了多个功能代码,其中一个功能需要提前上线如图所示,红框部分为我本次需要上线的功能提交记录代码,绿框部分为我已选择上线成功,可以看到红框与绿框直接的内容并没有被带入master分支.这里我以IDEA为例.首先,切换到master分支,也就是你需要......
  • 【题解】Solution Set - NOIP2024集训Day2 线段树
    【题解】SolutionSet-NOIP2024集训Day2线段树https://www.becoder.com.cn/contest/5431「CF1149C」TreeGenerator™结论:对于括号序列的一个子段,删去所有的匹配括号之后,剩下的不匹配的括号,按顺序构成树上的一条路径。Why?从括号序列的构造出发。每次(相当于开始遍历......
  • 网站源码医疗机构pbootcms模板网页设计主题
    医疗机构的网站设计分享我很高兴向大家介绍我刚刚制作的医疗机构的网站设计。友好的站点界面,是打动访客的第一步。医疗机构网站的主题网站设计需要充分考虑到医疗行业的特殊性和用户需求,以下是一个清晰的设计介绍:1.设计原则用户友好性:网站的设计和功能应便于用户理解和使......
  • P3834 【模板】可持久化线段树 2
    P3834【模板】可持久化线段树2-洛谷|计算机科学教育新生态(luogu.com.cn)#include<bits/stdc++.h>usingnamespacestd;usingi64=longlong;template<classNode>structPersidentSegmentTree{#definelc(u)tr[u].l#definerc(u)tr[u].r#definesum(u)t......