首页 > 其他分享 >写模板,线段树

写模板,线段树

时间:2024-03-28 13:58:41浏览次数:21  
标签:Node sz lazy return int 线段 区间 模板

1 意义:线段是是为了对区间中的元素进行操作,而衍生出来的一种数据结构,比如区间加减,区间求和。 线段树将1~n的区间分解成4n个小区间。
2 过程:区间修改就是对一个或者多个节点按照设定的规则对数值进行修改。区间查询就是对一个或多个节点查询的结果按规则进行合并,得到最终结果。 其中区间修改增加了懒人标记功能,该功能也可以叠加,但是在对当前区间点进行修改时,需要先把懒人标记向下传播一层。

3 主要手撕功能:update(); query(); merge重载的实现。 pushDown |= 懒人标记重叠的实现。

struct Node{
	long long value;
	bool is_lazy;
	Node(bool state = false):  is_lazy(state){}

	Node operator + (const Node& other){
		Node res = *this;
		res.value += other.value;//决定了如何合并两个区间的值
		return res;
	}

	Node operator |= (const Node& other){
		//这里决定了如何合并多个懒人标记的逻辑
		is_lazy = true;
	}


};

template<typename T>
class SegmentTree{
public:
	explicit SegmentTree(int sz): sz_(sz){
		st_.resize(4 * sz_);
		lazy_.resize(4 * sz_);
	}

	void update(int i, int j, T val){
		update(1, 1, sz_, i, j, val);
	}

	T query(int i, int j){
		return query(1, 1, sz_, i, j);
	}


private:
	int sz_;
	vector<T> st_;
	vector<T> lazy_;
	const T flag_{};

	T merge(T a, T b){
		return a + b;
	}

	void pushDown(int p, int l, int r){
		if (lazy_[p].is_lazy){
			st_[p].update(lazy_[p], r - l + 1);
			if (l != r){
				lazy_[p << 1] |= lazy_[p];
				lazy_[p << 1 | 1] |= lazy_[p];
			}
			lazy_[p] = flag_;
		}

	}

	void update(int p, int l, int r, int i, int j, T val){
		pushDown(p, l, r);
		if (i > j){ return; }
		if(l >= i && r <= j){
			lazy_[p] = val;
			pushDown(p, l, r);
		}
		else{
			int mid = (l + r) >> 1;
			update(p << 1, l, mid, i, min(mid, j), val);
			update(p << 1 | 1, mid + 1, r, max(mid + 1, i), j, val);
			st_[p] = merge(st_[p << 1], st_[p << 1 | 1]);
		}
	}

	T query(int p, int l, int r, int i, int j){
		pushDown(p, l, r);
		if (l >= i && r <= j){
			return st_[p];
		}
		int mid = (l + r) >> 1;
		if (j <= mid){
			return query(p << 1, l, mid, i, j);
		}
		else if (i > mid){
			return query(p << 1 | 1, mid + 1, r, i, j);
		}
		return merge(query(p << 1, l, mid, i, j), query(p << 1 | 1, mid + 1, i, j));
	}
};

标签:Node,sz,lazy,return,int,线段,区间,模板
From: https://www.cnblogs.com/yxcblogs/p/18101488

相关文章

  • 最近公共祖先(lca)倍增算法【模板】
    P3379【模板】最近公共祖先(LCA)-洛谷|计算机科学教育新生态(luogu.com.cn)#include<bits/stdc++.h>#include<cstdio>usingnamespacestd;constintN=5e5+100;constintinf=0x3f3f3f;intn,m,s;vector<int>g[N];intdep[N];//存u点的深度intfa[N][20];//存从u......
  • Floyd算法 【多源最短路】模板
    B3647【模板】Floyd-洛谷|计算机科学教育新生态(luogu.com.cn)#include<bits/stdc++.h>usingnamespacestd;constintN=1e2+10;constintinf=0x3f3f3f;intn,m;intg[N][N];voidfloyd(){for(intk=1;k<=n;k++){for(inti=1;i<=n;i++)......
  • 泛型编程之模板
    1.函数模板重要行:template<typenameT,typenameT1>关键值class和typename含义相同,那么我们以后就使用typename即可。 一般情况下的格式:template<模板参数列表>返回值类型函数名(函数参数) 模板参数列表的理解:函数参数列表在运行时调用者用实参来初始化形参而......
  • 消息sms 邮箱/手机号/push发送的方案 & 定时任务xxlJob灵活度 & 泛型和发送的模板类设
    消息sms邮箱/手机号/push发送的方案&定时任务xxlJob灵活度&泛型和发送的模板类设计1.消息sms邮箱/手机号/push发送的方案1.判断收件人地址是否为空,不为空则发送邮件。为空则不发送。可以通过该方法终止一些消息的发送。2.收件人的地址可以配置在Apollo中,直接删除该key......
  • Kruskal最小生成树【详细解释+动图图解】&【sort中的cmp函数】& 【例题:洛谷P3366 【模
    文章目录Kruskal算法简介Kruskal算法前置知识sort中的cmp函数算法思考样例详细示范与解释kruskal模版code↓例题:洛谷P3366【模板】最小生成树code↓完结撒花QWQKruskal算法简介Kr......
  • 24/3/27 线段树
    (1)P4145上帝造题的七分钟2/花神游历各国水。$\color{blue}\text{Code}$#include<iostream>#include<cmath>usingnamespacestd;#defineintlonglongconstintN=1000010;intn,m,a[N],k,l,r;#definels(u<<1)#definers(u<<......
  • 代码模板
    manacharvoidinit(){ cnt=1; ss[0]='!'; ss[cnt]='#'; len=strlen(s); for(inti=0;i<len;i++) { ss[++cnt]=s[i]; ss[++cnt]='#'; }}intmanachar(){ d[1]=1; for(inti=2,l,r=1;i<=cnt;i++) { if(i<r)d[i]=m......
  • react零基础到精通-1|基础概念,主要特性,s6语法,react相关的开发环境和工具,react简介,箭头
    致力于解决复杂视图层开发我呢提,全新的ui组件的开发理念,1.1React简介前端UI的本质问题是如何将来源于服务器端的动态数据和用户的交互行为高效地反映到复杂的用户界面上。React另辟蹊径,通过引入虚拟DOM、状态、单向数据流等设计理念,形成以组件为核心,用组件搭建UI的开发......
  • 洛谷 P8306 【模板】字典树
    写模板:1确定树的节点指针数量2确定起始字符3实现插入方法4根据题目编写求解方法,或者添加计数元素到节点中structNode{array<int,100>next{};intcnt=0;};classTrie{public:Trie(charstart):start_(start),root_(0){trie_.resize(1)......
  • [普及+] 模板口胡
    差分约束系统省流:给出\(n\)个数,\(m\)个不等式,每个形如\(x_a-x_b\lew\),求通解。转化一下,\(x_a\lex_b+w\)这不就是图论点转移吗,连一条\(x_b\tox_a\)权值为\(w\)的边,最后要求通解即求当前点集权值满足所有边。不妨这样想,确定一个点,再更新其它点。这不就是最短路吗......