简介 树链剖分,顾名思义,就是把树剖分成链,在链上进行一系列的操作。 下面我们就来学习一下这个算法。 概念 树链剖分引入了很多新的概念: 重儿子:一个节点所有的儿子中子树\(size\)最大的儿子。 轻儿子:一个节点的儿子中除了重儿子都是轻儿子。 重边:一个节点与它的重儿子所组成的边。
树链剖分,顾名思义,就是对树剖分成链,然后用数据结构进行维护,以此降低维护的复杂度。 必备知识点 邻接表存图 LCA 线段树 相关定义 重儿子:一个节点所有子节点中以其为根的子树的节点最多的节点 重边:一个节点到其重儿子的边 重链:一条全部由重边构成的路径(特别地,一个节
1672. [SPOJ 375] 难存的情缘 ★★★ 输入文件:qtree.in 输出文件:qtree.out 简单对比时间限制:1 s 内存限制:256 MB 【题目描述】 一天机房的夜晚,无数人在MC里奋斗着。。。 大家都知道矿产对于MC来说是多么的重要,但由于矿越挖越少,勇士们不得不跑到更远的地方挖矿,但
1672. [SPOJ 375] 难存的情缘 ★★★ 输入文件:qtree.in 输出文件:qtree.out 简单对比时间限制:1 s 内存限制:256 MB 【题目描述】 一天机房的夜晚,无数人在MC里奋斗着。。。 大家都知道矿产对于MC来说是多么的重要,但由于矿越挖越少,勇士们不得不跑到更远的地方挖矿,但
最近目标 并查集: P2024 [NOI2001]食物链 P1525 关押罪犯 (二分+二分图)(并查集代表监狱)(并查集代表犯人之间的关系) 动态规划dp: P2016 战略游戏 P1352 没有上司的舞会 P1273 有线电视网 P3354 [IOI2005]Riv 河流 P3140 [USACO16FEB]再探圆形谷仓Circular Barn R… P3112 [USACO14D
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3531 解题心得: 关于树剖的部分很容易想到,树上的简单路径维护值的问题肯定是要树链剖分了,但是线段树怎么维护就很讲究了,因为有不同的阵营,如果维护每个阵营就需要建立n颗线段树,如果静态建立线段树肯定会MLE,这里就
题目链接:https://www.luogu.org/problem/P3833 题目大意:有一颗含有n个节点的树,初始时每个节点的值为0,有以下两种操作: 1.Add u v d表示将点u和v之间的路径上的所有节点的值都加上d。 2.Query u表示当前果树中,以点u为根的子树中,总共有多少个果子? 解题思路:树链剖分板子,具体看代码注
树链剖分 对于一棵树上两个节点所构成的链的操作,我们可以用树链剖分,来将树转化为多条链的集合(线性结构),从而将树上链的结构转化为线性结构的区间操作. 找出每个节点的重儿子(包含节点最多的儿子) 重儿子优先输出dfs序 对于如下一棵树进行剖分 找出其重儿子(红色线) 每个节
#include<bits/stdc++.h> #define lson(x) (x << 1) #define rson(x) (x << 1 | 1) using namespace std; const int N = 100010,M = 200010; int n,m,r,p; long long a[N]; int d[N],son[N],fa[N],siz[N],top[N],rk[N],id[N],cnt;//树链剖分 int head[N],edg
树链剖分维护的都是点,而这道题要求的是边。 解决:就把边权下放,变成点权,注意下放后查询u到v的路径时要除去lca的点权,因为lca的点权是其父亲的边权 细节:线段树的加标记与等于标记的维护与下传 #include<bits/stdc++.h>using namespace std;#define N 100005#define mid ((l+r)>>1)in
题目描述 给一棵树,每个节点有一种颜色和权值,有四种操作:将一个节点颜色改变,讲一个节点权值改变,求一上路径上某种颜色的的点的权值和,求一条路径上某种颜色的点的最大权值 N,Q < =105 , C < =105 数据保证对所有QS和QM事件,起点和终点城市的信仰相同;在任意时刻,城市的评级总是不大于
原文链接 导言 你会DFS序吗? 我想,你肯定会说会.不会,欢迎点击搜索和DFS序学习 你会线段树吗?不会,欢迎点击暂无 我想,身为巨佬的你肯定会. 既然巨佬你会DFS序,会线段树.那么接下来的树链剖分,你也一定会. 接下来的学习,您必备的算法知识有,DFS序,线段树. 您可以选修的知识点有树上
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int MAXN=2*1e6+10; #define ls k<<1 #define rs k<<1|1 inline char nc() { static char buf[MAXN],*p1=buf,*p2=buf; return p1==p2&&(p
1 #include<bits/stdc++.h> 2 #define lson(x) (x << 1) 3 #define rson(x) (x << 1 | 1) 4 using namespace std; 5 6 const int N = 100010,M = 200010; 7 int n,m,r,p; 8 long long a[N]; 9 int d[N],son[N],fa[N],siz[N],top[N],rk[N],id[N]
题目链接:https://nanti.jisuanke.com/t/39272 题意:给一棵树,n个结点,树根为1,n-1条边,每个结点有一个权值。进行3种操作: 1 s t:把1和s之间的最短路径上的所有结点|t。 2 s t:把1和s之间的最短路径上的所有结点&t。 3 s t:把1和s之间的最短路径上的所有结点进行异
题目链接:https://www.luogu.org/problemnew/show/P3384 题意:树链剖分模板题,但是比较坑的是要注意取模,每个可能炸int的地方都要加取模。 代码如下: #include<cstdio>#include<algorithm>using namespace std;const int maxn=100005;//链式向前星int cnt1,head[maxn],w[maxn],wt[maxn
今天是本蒟蒻在杭州集训(被虐)的第四天,由于我太弱了,出题人不屑于浪费时间出毒瘤题来坑我;而是从洛谷上 挪了些原题上来;但由于我太弱了,还是没做出来; T1 . 坐等 memset0 树链剖分是个喜欢逛讨论区的女孩子。树链剖分看到有若干个小学生发的帖子,因为一些原因,这些帖子形成了一条链。其中第
功能: 修改与查询整个子树 修改与查询路径 #include<bits/stdc++.h>using namespace std;//input by bxd#define rep(i,a,b) for(int i=(a);i<=(b);i++)#define repp(i,a,b) for(int i=(a);i>=(b);--i)#define RI(n) scanf("%d",&(n))#define RII(n,m) scanf(&
题意: M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门。为了让分布在世界各地的N个部门之间协同工作,公司搭建了一个连接整个公司的通信网络。该网络的结构由N个路由器和N-1条高速光缆组成。每个部门都有一个专属的路由器,部门局域网内的所有机器都联向这个路
建议到UOJ上去交 题解 一眼\(DP\),先把转移方程写出来 设\(dp[i]\)为从点\(i\)出发到点\(1\)的最小费用,那么存在转移 \[f[i]=min\{f[j]+(d[i]-d[j])p[i]\}+q[i]=min\{f[j]-d[j]p[i]\}+d[i]*p[i]+q[i]\] 这个式子看起来可以斜率优化啊,往下化几步,可以得到类似下面的东西: 若\(d[j] < d[
#include<bits/stdc++.h> #define N 100010 #define INF 0x3f3f3f3f #define eps 1e-10 #define pi 3.141592653589793 #define P 1000000007 #define LL long long #define pb push_back #define fi first #define se second #define cl clear #define si size #defin
https://nanti.jisuanke.com/t/39277 题意 给出一棵树,以及树边权,求出这个公式 题意 这里规定了偏序关系,所以不用重复计算两次。 将这题转化为求两个点所做的贡献。 首先要明白异或的性质。 a ^ b = 0 等价于 a = b 那么a到b这条链上异或等于0等价于,a到根的异或值 = b到根
树链剖分 问题 将树上x到y最短路径上所有结点的值都加上z 可以用树上差分,cf[x]+=z ; cf[y]+=z; cf[lac(x,y)] -= z; cf[fa[lca(x,y)]] -= z; 求树上从x到y结点最短路径的点权和或者边长和 dist = dis[x] + dis[y] - 2*dis[lac(x,y)],dis[x]代表结点x到root的距离,可以通过dfs预
最近写动态点分治快自闭了QAQ....... 有时间再来写一下题解. 其实我不会告诉你我还没调出来呢QAQ Code: // luogu-judger-enable-o2// luogu-judger-enable-o2#include <bits/stdc++.h>#define setIO(s) freopen(s".in","r",stdin) // ,freopen(s".out","w",stdo
https://www.luogu.org/problemnew/show/P3384 知识点 :1.先切割重边,还记得求出top 2.线段树维护dfs序下的val数组,一条链上的数在dfs序中是连续的 3.求值时就在树上跑,优化在于一条链上的信息可以直接求,顾跳top即可 There is a false in the code : False 1 #