题解 \(by\;zj\varphi\) 观察可发现一个点向它的子树走能到的白点,黑点数是一个斐波那契数列。 对于白色点对,可以分成两种情况: 两个白点的 \(lca\) 是其中一个白点 两个白点的 \(lca\) 是一个黑点 注意,两个白点的 \(lca\) 不可能是非两个白点之中的白点。 分开计算即可 Code
传送门 找规律真挺晕的……我画了两个图全画错了 但不康题解真想不到解法 发现一棵黑色节点为根的子树中每层白色节点个数为斐波那契数 然后题解很神仙的分出了两种情况 当两个点的lca是白色点时,可以枚举距离,则lca的深度范围可知,就可求了 当lca为黑色点时,可以\(n^3\)分别枚举根节
\[\huge \rm 虚树 \] \[\Large\rm 算法简介 \]\(\quad\)在一些问题中,我们只关心一些关键点的信息,同时我们需要维护他们之间的树形结构,于是可以想到将它们和它们之间的 \(\rm LCA\) 拉出来建一颗树,这棵树就被称作虚树。 \(\quad\)有一个朴素的想法,就是对它们两两求 \(\rm LCA\),并且
题目链接 #1.0 基本思路 首先需要理解这个 "mex" 的含义,我们需要找出所有的路径使得 \(i\) 是编号最小的未出现的点,那么也就意味着 \([0,i-1]\) 应当全部包含在我们要找的路径中。那么我们便可以尝试维护这样的路径:路径两端 \(x, y\in[0,i-1]\),\([0,i-1]\) 包含在路径经过的点集
题目传送门 双倍经验哒 算法分析:欧拉序+并查集 太弱了不会 LCT 没办法…… 提供一种不需要 LCT 的解法。 题目里虽说在线操作,但我们可以把操作先存下来。注意到按照顺序进行操作,最后得到的树是固定的,因此我们可以利用并查集,仅执行 bridge 操作,把树先建好。这样整个问题就转化为,在
CF1000G Two-Paths 题解 题意 给定一颗树,询问一条以 u,v 为起点与重点的路径的 点权和-边权和, 每条边最多经过两次,点权仅能算一次所能得到的最大值。 思路:换根DP 首先对于上面这个图,我们可以发现整个路径的特征,边的编号表示一种可能的遍历顺序: 1.(其实可以先遍历 u 的子树,只不过
比赛链接:https://codeforces.com/group/2g1PZcsgml/contest/337661 A,D,K,3/12,第11名,还好。 A他们挺快写出来了。D我感觉可以用上一场A一样的做法,成功。G用AC自动机把K过了;字符串的板子我还都老生疏了,真惭愧。其他题看来看去都没有成熟的思路,直到比赛结束。G最后十五分钟用分治猛改J
虚树一般用于树形DP中,此类问题通常询问次数很多但每次询问涉及到的点数很少。若每次询问均对整棵树进行DP,时间复杂度是巨大的。所以我们采用虚树这种数据结构。 虚树的构建 虚树由询问点和询问点的LCA构成。 我们可以先处理出原树的dfs序,从dfs序由小到大来遍历询问点,并通过栈来维
C 简要题意 给定一棵n个点的树,再给定m对点,每对点表示一条路径。求一个最小点集,使得每条路径上都存在点集中的点。 数据范围 \(1\leq n,m\leq 10^5\) 简要题解 据说树上路径问题常常和LCA有关,于是我们对于每一条路径,考虑它的LCA。 对于LCA最深的那一条路径,一定把LCA放入点集是最优
LCA 即最近公共祖先,是指在有根树中,找出某两个结点u和v最近的公共祖先。 在一棵没有环的树上,每个节点肯定有其父亲节点和祖先节点,而最近公共祖先,就是两个节点在这棵树上深度最大的公共的祖先节点。 换句话说,就是两个点在这棵树上距离最近的公共祖先节点。 所以LCA
文章目录 倍增法题目 倍增法 一篇博客 最常用,也是最简单的算法,实质就是直接对暴力使用倍增优化将复杂度降低达到需求。 d e p t
树上问题中,有个相当著名而又较为困难的问题,即最近公共祖先问题(Least Common Ancestors),又简称LCA问题。我们先了解一下何为LCA吧。 LCA,即已知一棵有根树,求问两个节点的最近的公共祖先是哪个节点。 从最朴素的算法去思考,我们只要找到这两个节点的深度,先从最深的节点向上搜索,找到与另
Perfect binary trees are one of the coolest structures that computer scientists study. They have a lot of properties that make them very nice to work with. One of the nicest properties is that they can just be described by a single integerngiving the dept
题目比较难读,因为n很小因此可以枚举哪一个点为根节点,计算每对逆序对的贡献(就是概率) 对于一个逆序对产生的贡献,可以看成较大节点先选中的概率,可以用dp预处理求出(u,v)到父节点p的概率 倍增求lca. https://codeforces.com/contest/1541/problem/D 挺难解释。。 倍增求lca 预处理o(n),每次
题目链接: Tree Array 题目大意: 给你一棵n个结点的数,你可以生成一个序列。 开始时,你随机地标记一个结点。任意时刻,那些没有标记但能通过一条边连接标记了的点的点构成一个集合,你从这个集合中等概率地标记一个点。重复操作,直到标记完所有点。 标记点的顺序就是这个序列,求这个序列逆
在一棵树上,我们要求点 $(u,v)$ 之间路径的第$k$大数。 对于点 $i$ ,建立 $i$ 到根节点的一棵前缀主席树。 简单容斥后不难得出结果为$sumv[u]+sumv[v]−sumv[lca]−sumv[fa[lca]]$ 其他的和主席树是一样的。Code: #include<cstdio> #include<cstring> #include<algorithm>
传送门 一道很简单的树形题目,求一下LCA然后模拟就好了。 #include <bits/stdc++.h> using namespace std; const int N = 1e3 + 10; int head[N], tot, n; int dep[N], fa[N][22]; struct Edge{ int v, next; }edge[N]; vector<vector<int> > vec(200); void add(int u, int v)
tag:虚树,重链剖分,交互,构造,二分 首先预处理一下以 \(1\) 为根,每个点到根的 \(dis\),然后用一次操作可以求出任意两点的 \(lca\),\(lca=dep_x\oplus dep_y\oplus query(x,y)\)。 可以考虑增量法,每次加入一个点,然后维护当前点集的虚树。 对于每次添加操作,首先对虚树重链剖分。 主要就
缓缓加速 第二日,生成树与LCA 从上至下知识点对应为: 1-3、最小生成树(MST),prim或kruskal算法 4、求多颗最小生成树(或许这么称呼不太严谨),kruskal算法 5、最大瓶颈生成树(MBST),prim或kruskal算法 6、LCA,树上倍增 7、最大生成树+LCA,树上倍增+Kruskal重构树 一些新内容,整理一下: 1、prim与
题目链接 交叉坐标的星尘 题意简述 题目中说的比较清楚 , 这里再粘贴一遍 : 给定一棵 \(n\) 个点的树 . 你需要从 \(1\) 号点开始 , 不断地给树上的结点染色 . 在某一轮染色过程中 , 假设你是从编号为 \(u\) 的结点开始染色 , 现在染色到编号为 \(v\) 的结点 , 那么下面你只能尝试
ST表 静态查询区间最值。 P3865 【模板】ST 表 ll f[100001][20]; ll n, m, a[100001]; void ST_make() { for (int i = 1; i <= n; ++i) f[i][0] = a[i]; ll t = log(n) / log(2) + 1; for (int j = 1; j < t; ++j) for (int i = 1; i <= n - (1 <
其实就是一个求LCA的模板问题。 我的实现方法是在p、q上分别打一个标记。然后递归把标记向上传递。当找到一个拥有两个标记的节点,它就是最近公共祖先。 /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; *
【模板】最近公共祖先(LCA) 题目 P3379 注:ybtoj问的是两点距离,即 d r o o t
pts: 100 T1: 100 T2: 0 T3: 0 吐槽:xj 中学的神仙题目,T1 贪心跑过了正解的 dp /se T1 Strategy 游戏中有 \(n\) 个敌人,面对第 \(i\) 个敌人,三种解决方案 花 \(attack_i\) 的代价主动进攻,此技能最多用 \(k\) 次 花 \(define_i\) 的代价防御,此技能可以用无数次 和该敌人结盟,此技能
题目描述 给定一个n个节点的树,每个节点表示一个整数,问u到v的路径上有多少个不同的整数。 输入格式 第一行有两个整数n和m(n=40000,m=100000)。 第二行有n个整数。第i个整数表示第i个节点表示的整数。 在接下来的n-1行中,每行包含两个整数u v,描述一条边(u,v)。 在接下来的m行中,每一行包含两