SP10628 COT - Count on a tree 给定一棵有 \(n\) 个节点的数,每个点有权值,每次操作输出节点 \(u,v\) 之间的第 \(k\) 小值。 因为有静态区间第 \(k\) 小,所以考虑主席树。 因为题目要求在树上操作,所以考虑树上差分。 建树的过程就是跑一个 dfs,每个节点继承其父节点的权值建树。
A. Food for Animals 优先买前两种,再用第三种。 B. Make It Increasing 感觉自己写复杂了。 \(dp_{i, j}\)表示第\(i\)个元素使用\(j\)次操作的代价。 \[dp_{i + 1, k} = \left\{ \begin{aligned} &\min_j dp_{i, j} + k & f(a_i, j) < f(a_{i + 1}, k)\\ &\inf &
Virtual Tree 揭开华丽的外衣, 关注问题的本质. 这就是虚树在做的事情, 所以虚树不虚, 反而是虚伪原树中最实在的部分, 所以它更应该被称作 "实树". 它在实际问题中常常回答完问题后就转瞬即逝, 所以给人的印象就是镜花水月一般的虚无飘渺, 现实中敢讲真话的人也有很多就这虚树一
P4211 [LNOI2014]LCA 分析 本题要计算的就是l~r与z的LCA的深度之和 我们来看看,是否可以将求多个dep转化一下 我们先对dep有一个理解,dep就是从i到root总共有多少点 我们从整体上考虑,发现对于一个询问:l , r , z 来说,所有的 lca 都在 z 到根的路径上。从而有一些点,它们对很多的 lca
luogu 模板:https://www.luogu.com.cn/problem/P3379 #include <bits/stdc++.h> using namespace std; const int N = 5e5 + 10; int n, m, root, d[N], p[N][30], lg[N]; vector <int> g[N]; void dfs(int u, int fa){ p[u][0] = fa; d[u] = d[fa] + 1; for (in
原题链接在这里:https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree-iii/ 题目: Given two nodes of a binary tree p and q, return their lowest common ancestor (LCA). Each node will have a reference to its parent node. The definition for No
早早的到工作室做准备,刚开始调环境的时候出了点问题,后面位置错开通过了。刚开题还是比较顺利,写完前6题,我大致的看了眼后面的题型,简单计算,模拟,栈,排序,感觉有点像LCA。由于两天前复习到LCA,我打算先开LCA这题(感觉PTA考树基本都是模板),一眼没怎么看懂题意,我就又先把第7题写了,
主要内容是LCA的板子 1.倍增LCA 原理:尝试法,二进制划分和倍增 打法: 1.首先预处理每个节点在整棵树中的深度和关键信息 2.对于节点x,预处理每个2的j次方所能到达的点,这里递归变递推 3.询问lca的时候,首先调整节点的深度,较深的节点走到与较浅节点同深度位置 4.如果y走到x的位置,那么返回
模板题:静态区间的第k小 主席树:可持久化线段树,可以支持查询历史版本的线段树。 在模板题中,对数组的每一个前缀建立一棵权值线段树,线段树的每一个节点维护属于区间\([l,r]\)的数的个数。 对于询问\([l_i,r_i]\)中的第\(k_i\)大的数,利用前缀的思想,版本\(r_i\)与\(l_{i-1}\)之间的差就
2022-04-10 树链剖分,理解完只有惊叹。 前置知识: 链式前向星: 需要的变量: cnt 记录边数 edges{ to,w,next}的数组,存储边 head[maxn]存储每个节点的最新的那条边 1 //链式前向星,储存图的方式,思想是前向 2 //相当于一个邻接表的每一行的链表,向最前端插入 3 4 #include<iostre
1. 定义: LCA(Least Common Ancestors),即最近公共祖先,是指在有根树中,找出某两个结点 \(x\) 和 \(y\) 最近的公共祖先(深度最大的祖先),记为:\(LCA(x,y)\)。 举例: \(LCA(15,12)=4\) \(LCA(10,12)=10\) 图例: 作用:能在 \(log(n)\) 解决从 \(u\) 到 \(v\) 的路线问题。 2. 求解: 方法一:向上
附:邻接表存树 LCA问题简述 自己是自己的祖先 向上标记法 一般不用 从x向上走到根节点, 并标记路径上经过的点 从y向上走到根节点, 当遇到第一个被标记的点就找到了LCA(x, y) 倍增法 fa[i][j]表示从i开始,向上走2^j步所能走到的结点。0 <= j <= logn depth[i]表示深度 哨兵:如果从i
本篇随笔简单讲解一下信息学奥林匹克竞赛中树上差分的相关知识点。树上差分近几年成为了考试热门,也成为了考察差分思想比较常用的手段。理解树上差分最好需要读者了解图和树的基础知识,\(LCA\)及\(LCA\)问题的求法,以及差分数组和差分思想。 一、边的差分 我们对差分和差分数组的理
树-相关算法 定义 任意两个节点之间只有唯一一条路径的无向图 \(n\)个节点,\(n - 1\)条边 建树方法 链式前向星(提供边的信息) //存储 struct edge{ int to; int pre; }e[ll]; //加边 void add(int x, int y){ e[++cnt].to = y; e[cnt].pre = last[x]; l
\(\texttt{Solution}\) 我们考虑 \(\mathcal O(nq)\)怎么做 我们可以发现如果一个点是关键节点,那么这个点下面的关键节点是一定要删去的,如果这个点不是关键节点,那么如果他下面有两个以上的关键节点,把他传到上面去再把这个点删掉只会更劣不会更优,而如果只有一个关键节点,传到上面去
P7518 [省选联考 2021 A/B 卷] 宝石 题目来源 乍一看没有任何思路,于是当年我打了一个模拟程序混了点分就跑路了……然后现在还是得看题解……还得努力啊 这里用主席树+倍增+二分,复杂度O(nlog2 (n)),理解起来较为简单,但是对我来说太难想了。 一、题目初步转化 1.其实这道题也
CF814E 首先不难观察到我们的整个图可以看做树边和非树边,注意到答案之和所有点的度数有关,而转移的时候所需要的所有信息其实是 \(2\) 度点的个数和 \(3\) 度点的个数,以及当前层的点数,我们可以让一个 dp 数组当前层值关注树边,另一个 dp 数组帮助转移。可以写出 dp 式子。dp 式子前
The lowest common ancestor (LCA) of two nodes U and V in a tree is the deepest node that has both U and V as descendants. Given any two nodes in a binary tree, you are supposed to find their LCA. Input Specification: Each input file contains one test case
传送门 题意 一棵 \(n\) 个节点的树,\(m\) 次修改,给 \(u\) 到 \(v\) 路径上每一个点一件种类为 \(z\) 的物品,求最后每个节点个数最多的物品种类。 思路 将题意再精简一下就是维护树上单点染色众数,修改是一条链。 (1)树上差分 想到修改一条路径其实可以用树上差分的思想,将路径划分为两
首先考虑枚举lca的做法,对于每一个lca枚举其子树中所有节点,时间复杂度$O(n^2)$显然过不了 再思考发现这是一个针对子树的询问操作,考虑dsu on tree来统计答案 开一个新数组vec[x],其中x为权值,记录了所有权值为x的编号 那么只需要每次计算一颗新子树时,先累加答案,再更新vec数组(如果同时
倍增LCA LCA:已知一个树和书上两个点,求两个点的最近公共祖先。 倍增:将2的所有次幂排成一个序列,相加可以得到所有正整数,这样就可以在找最近公共祖先时不是一层一层找而是每次找2的幂次方层,大大提高算法效率。 算法思路: 1,用链式前向星存图,找到根节点并从根节点开始进行深度优先搜索,
对于路径 \((u,v)\) 和 \((s,t)\) 判断是否有交: 对于两点 \(\operatorname{LCA}\) 的深度较大者,判断它是否在另一条路径上 求交出来的路径 \(\operatorname{LCA}(u,s),\operatorname{LCA}(u,t),\operatorname{LCA}(v,s),\operatorname{LCA}(v,t)\) 四者中,深度较大的两个即为
DFS序 DFS 序就是DFS得到的序列(简洁明了) DFS 序擅长处理子树的问题, 可以发现 子树是这个子树根节点入栈到出栈的整个序列 DFS 序把子树修改转化为了区间修改的问题。 「HAOI2015」树上操作 要对一个树进行操作, 支持点修改, 子树修改, 查询某个节点到跟节点的距离。 对于树剖就是版子
tarjan求LCA 前言 tarjan求LCA的时间复杂度是\(O(n+2*q)\),是非常优秀的复杂度,但缺点就是只能离线。(懂了,去学欧拉序\(O(1)\)求LCA) tarjan求LCA需要用到并查集,本人用的代码: int f[N]; void cz(int x){return x==f[x]?x:f[x]=cz(f[x]);} void hb(int x,int y){f[cz(x)]=cz(y);} tarj
LCA 向上标记法 时间复杂度 O ( n ∗ m ) O(n*m) O(n∗m)