2025/5/2集训(下午)

线段树

钟神说要讲一天线段树,就很炸裂

开头钟神的一条寄语:

不爆int千万不要开#define int long long这种东西
不然有时可能会亖的很惨
                                          ——钟皓曦
//a = b+c*d;
	a = (b + 1ll * c * d) % mo;//乘法转long long
	
	//a = b*c*d + e*f + g;
	a = (1ll * b * c % mo * d + 1ll * e * f + g) % mo;//三次方会爆long long,所以在里面也要取模
	
	//a = a + b;
	a += b; if (a >= mo) a-=mo;//比取模快很多
	
	//a = b*c-d*e
	a = ((1ll * b * c - 1ll * d * e) % mo + mo) % mo;//c++对负数取模还是负数,所以要把模数再加上
	
	//a = a - b
	a -= b; if (a<0) a += mo;//取模很慢

正题:

线段树是基于分治思想的二叉树,用来维护区间信息(区间和,区间最值,区间GCD等)

可以在 \(\log n\) 的时间内执行区间修改和区间查询。

线段树中每个叶子节点存储元素本身,非叶子节点存储区间内元素的统计值。

以下为一个线段树的建立例子:

(1) 用分治法自顶向下建立,每次建立,左右子树各一半

(2) 每个节点都表示一个"线段"区间,非叶子节点包含多个元素,叶子节点只有一个元素

(3) 除最后一层外,上面的每一层都是满的、

(4) 节点的数量不超过 \(4\times n - 1\) --> 数组开四倍

在线段树的存储上采用的是二叉树的存储方式

(1) 根节点为\(1\)号节点

(2) 以 \(i\) 为编号的儿子节点编号为 \(2 \times i\),\(2 \times i + 1\)

但是通常以 i << 1i << 1 | 1 来表示

对于线段树需要掌握的操作为:

(1) pushup()

(2) pushdown()

(3) build()

(4) query()

(5) update() / modify()

在线段树的修改操作里 有单点修改 和 区间修改(难)

特别的对区间修改进行补充说明:

例如,对某个区间内的每个数加上\(5\)

如果修区间 \([x,y]\)所覆盖的每个叶子节点,时间将是\(O(n)\)

我们做懒惰修改,当\([x,y]\)完全覆盖节点区间\([a,b]\)时,

先修改该区间的 sum 值,再打上一个 "懒标记" 然后立即返回。

等下次需要时,再下传 "懒标记"。这样,可以把每次修改和查询的时间都控制到$ O(\log n)$

线段树结构体:

struct node{
    //定义变量
}tr[maxn*4]

模板伪代码:

void build(int u,int l,int r){
	tr[u]={l,r};
	if(l==r) return;
	int mid=l+r>>1;
	build(u<<1,l,mid);
	bulid(u<<1|1,mid+1,r);
}

int query(int u,int l,int r){
	if(tr[u].l>=l&&tr[u].r<=r) return tr[u].v;
	int mid=tr[u].l+tr[u].r>>1;
	int v=0;
	if(l<=mid) query(u<<1,l,r);
	if(r>mid) v=max(v,query(u<<1|1,l,r));
	return v;
}

void update(int u,int x,int v){
	if(tr[u].l==x&&tr[u].r==x) tr[u].v=v;
	else{
		int mid=tr[u].l+tr[u].r>>1;
		if(x<=mid) modify(u<<1,x,v);
		else modify(u<<1|1,x,v);
		pushup(u);
	}
}

如果感觉u<<1,u<<1|1,tr[u].l,tr[u].r用的太多打字太累,可以直接用下面的宏定义:

#define ls u<<1
#define rs u<<1|1
#define lt tr[u].l
#define rt tr[u].r
(注:pushuppushdown不定,没有具体模板)

洛谷线段树模板传送门:

P3372 线段树1
P3373 线段树2
P6242 线段树3(线段树进阶内容)

posted on 2025-05-02 19:06  穆昕雨  阅读(32)  评论(0)    收藏  举报

导航