首页 > 其他分享 >树链剖分

树链剖分

时间:2024-09-02 14:53:21浏览次数:9  
标签:opt 剖分 int cin 树链 Build

原理:将一棵树剖分成一条条的链,从而降低时间复杂度

首先会一个线段树,书完成剖分后,用来维护每一条的信息。

#include <bits/stdc++.h>
typedef int intt;
#define int long long
#define lc k << 1
#define rc k << 1 | 1
const int M = 2e6 + 10;
using namespace std;
int n,m,ans;
int a[M];
struct node{
	int l,r;
	int sum;
	int lazy;
}t[M << 2];
void Pushup(int k){
	t[k].sum = t[lc].sum + t[rc].sum;
}
void Pushdown(int k){
	if(t[k].lazy){
		t[lc].lazy += t[k].lazy;
		t[rc].lazy += t[k].lazy;
		t[lc].sum += (t[lc].r - t[lc].l + 1) * t[k].lazy;
		t[rc].sum += (t[rc].r - t[rc].l + 1) * t[k].lazy;
		t[k].lazy = 0;
	}
}
void Build(int k,int l,int r){
	t[k].l = l,t[k].r = r;
	if(l == r){
		t[k].sum = a[l];
		return ;
	}
	int mid = (l + r) >> 1;
	Build(lc,l,mid);
	Build(rc,mid + 1,r);
	Pushup(k);
}
void Modify(int k,int l,int r,int d){
	if(t[k].r < l || t[k].l > r) return;
	if(t[k].l >= l && t[k].r <= r){
		t[k].lazy += d;
		t[k].sum += (t[k].r - t[k].l + 1) * d;
		return ;
	}
	Pushdown(k);
	Modify(lc,l,r,d);
	Modify(rc,l,r,d);
	Pushup(k);
}
void Query(int k,int l,int r){
	if(t[k].r < l || t[k].l > r) return;
	if(t[k].l >= l && t[k].r <= r){
		ans += t[k].sum;
		return ;
	}
	Pushdown(k);
	Query(lc,l,r);
	Query(rc,l,r);
}
intt main(){
	cin >> n >> m;
	for(int i = 1;i <= n;i++) cin >> a[i];
	Build(1,1,n);
	while(m--){
		int opt;
		cin >> opt;
		if(opt == 1){
			int x,y,k;
			cin >> x >> y >> k;
			Modify(1,x,y,k);
		}
		else {
			int x,y;
			cin >> x >> y;
			Query(1,x,y);
			cout << ans << "\n"; 
			ans = 0;
		}
	}
	return 0;
}

标签:opt,剖分,int,cin,树链,Build
From: https://www.cnblogs.com/Nefert/p/18392714

相关文章

  • 树链剖分
    树链剖分的思想及能解决的问题树链剖分用于将树分割成若干条链的形式,以维护树上路径的信息。具体来说,将整棵树剖分为若干条链,使它组合成线性结构,然后用其他的数据结构维护信息。树链剖分(树剖/链剖)有多种形式,如重链剖分,长链剖分和用于Link/cutTree的剖分(有时被称作「实链剖......
  • #8. 「模板」树链剖分
    题目传送门:#8.「模板」树链剖分、前置知识重链:重链(HeavyPath)是指树链剖分中的一条主要的路径,该路径上的节点数量较多,相邻节点之间的距离较近。轻链(LightPath)是指树链剖分中的其他路径,相邻节点之间的距离较远。LCA:最近公共祖先分析上树状数组首先,我们需要定义一个......
  • 重链剖分
    思想我先给出一些定义:定义一个结点的重子节点为其子节点中子树节点数最大的子节点,如有多个,随便取一个作为重儿子,如果没有子节点,就没有重儿子。定义一个结点的轻子节点为其除重子节点外的子节点。从这个节点到重子节点的边为重边,到其他子节点的边为轻边。由重边首位相连的链......
  • 算法总结-树链剖分
    算法总结-树链剖分概念重儿子(红点):父节点\(f\)的子节点中子树大小最大的儿子。轻儿子(蓝点):父节点\(f\)的子节点中除重儿子以外的节点。重链(橙圈框出的链):链顶为轻儿子,由重儿子组成的链。重链剖分用处:将树上任意一条路径划分成不超过\(\log{n}\)条连续的链(如实......
  • 对树链剖分的爱 题解
    前言题目链接:洛谷。题意简述给出一棵\(n\)个节点以\(1\)为根的有根树。对于第\(2\leqi\leqn\)个节点,其父亲\(f_i\)在\([l_i,r_i]\)中均匀随机。每个树的边有边权,初始为\(0\)。现在有\(m\)次操作,第\(i\)次操作表示将\((u_i,v_i)\)的路径上所有的边的权值统......
  • 算法学习笔记之树链剖分
    算法学习笔记之(熟练跑分)树链剖分PART1首先是第一部份,也就是熟练跑分最最最基础的用法——求\(LCA\)首先是树链剖分//图片出自董晓算法大概就是这样本质就是根据子树大小将一颗树剖分成若干条链然后更加方便地处理/加速处理信息所以直接上代码?不,还要证明树链剖......
  • 树链剖分
    具体见OI-wiki,下面是一些补充重链要求是极大的每个点都在某一个重链中,如果一个点是重子节点,那么其在与其父亲所连的边的重链中,否则在与其重子节点所连的边的重链中这一段的原因:我们走重链是不用关心的,因为同一重链的dfs序是连续的,我们可以用其他数据结构维护,我们只用关心这条......
  • 树链剖分
    前置知识时间戳在树的\(DFS\)中,以每个节点第一次被访问的顺序,依次给予\(N\)个点\(1-n\)的标记,通常用\(dfn[x]\)表示\(x\)号节点的时间戳。\(DFS\)序进行\(DFS\)时,对每个节点进入递归后以及回溯前各记录一次该点编号,最后产生\(2-n\)的序列即是\(DFS\)序,可设\(L[X]\)和\(R[X]\)......
  • Open3D 三维重建-Delaunay Triangulation (德劳内三角剖分)
    目录一、概述1.1原理1.2实现步骤1.3应用二、代码实现2.1关键函数2.2完整代码三、实现效果3.1原始点云3.2重建后点云Open3D点云算法汇总及实战案例汇总的目录地址:Open3D点云算法与点云深度学习案例汇总(长期更新)-CSDN博客一、概述        德劳内三角剖......
  • 树链剖分
    定义把树剖成一条条不相交的链,对树的操作就转化成了对链的操作概念重儿子:对于每一个非叶子节点,它的儿子中以那个儿子为根的子树节点数最大的儿子为该节点的重儿子轻儿子:对于每一个非叶子节点,它的儿子中非重儿子的剩下所有儿子即为轻儿子重边:连接任意两个重儿子的边叫做重......