合集-树论

摘要:原题链接 WARNING!!! 使用map代替数组不再可靠,因为map的插入查找修改复杂度均为 \(O(logn)\) ,即使unorder_map也不行!!! 题解 我们发现,当一个节点的深度之和已知时(这里认为是根节点),其相邻节点的深度之和也可通过某种方程转移而得,有人称这种方法为换根DP 具 阅读全文
posted @ 2024-03-19 22:00 纯粹的 阅读(19) 评论(0) 推荐(0)
摘要:原题链接 题解 请看code code #include<bits/stdc++.h> #define ll long long using namespace std; struct { ll to, val, head, times = 0; } edge[200005]; ll out[100 阅读全文
posted @ 2024-03-22 11:38 纯粹的 阅读(23) 评论(0) 推荐(0)
摘要:原题链接 题解 1.具体去考虑每个集合所包含的元素及其大小个数是非常繁琐的,所以我们考虑每个元素对答案的贡献 2. 令 \(f[now]\) 代表以 \(now\) 为根节点的答案 \(sizes[now]\) 代表以 \(now\) 为根节点所包含集合的个数 更新过程如下: \(f[now]+=f 阅读全文
posted @ 2024-03-25 14:30 纯粹的 阅读(27) 评论(0) 推荐(0)
摘要:原题链接 题解 1.该题等价于构建一颗k叉树,每个叶子节点都有一个权值 \(leaf_i\) ,树的权值为 \(\sum_{1}^{n}leaf_i\) ,在使树的权值尽可能小的情况下,使最深的叶子节点的深度也尽可能小,即使数的高度尽可能小 这个叫做哈夫曼树 2.构建过程如下:每次从队列中取出 \( 阅读全文
posted @ 2024-03-30 11:47 纯粹的 阅读(78) 评论(0) 推荐(0)
摘要:原题链接 题解 1.建议去B站上看看动画演示,你就明白怎么回事了 2.如何用代码实现呢?看完你就明白了 code #include<bits/stdc++.h> using namespace std; int num=0; int tree[3000006][75]={0}; int cnt[30 阅读全文
posted @ 2024-03-30 20:20 纯粹的 阅读(109) 评论(0) 推荐(0)
摘要:原题链接 题解 1.由于我刚刚才学字典树,所以我会告诉你这就类似字典树,对字符串终点节点加一,然后搜索统计最大前缀和 code #include<bits/stdc++.h> using namespace std; string s; int tree[2000005][65]={0}; int 阅读全文
posted @ 2024-03-30 20:37 纯粹的 阅读(35) 评论(0) 推荐(0)
摘要:原题链接 题解 1.修改树上某一段路径 ,最后问你单个点的最大值,很想区间修改,单点查询,且只查询一遍,所以我们往前缀和方向靠 2.一个节点只有一个父亲,所以从底到根的路径是一条链,我们可以在这里应用前缀和,标记策略为令 \(tree[now]++\) 代表 \(now\) 节点到根节点这条链上所有 阅读全文
posted @ 2024-04-02 13:50 纯粹的 阅读(38) 评论(0) 推荐(0)
摘要:原题链接 题解 1.小模拟+树上差分+lca code #include<bits/stdc++.h> using namespace std; int a[300006]={0}; vector<int> G[300005]; int depth[500005]={0}; int fa[50000 阅读全文
posted @ 2024-04-02 14:24 纯粹的 阅读(22) 评论(0) 推荐(0)
摘要:原题链接 题解 1.这k个城市一定是连成一团在中间的 2.把树展开,变成散发图,剩下的n-k个城市一定在最边缘的位置 3.拓扑排序 dalao's blog code #include<bits/stdc++.h> using namespace std; vector<int> G[100005] 阅读全文
posted @ 2024-04-02 19:19 纯粹的 阅读(323) 评论(0) 推荐(0)
摘要:原题链接 题解 树上只有两种颜色,我们把每种颜色的连通块记录下来,只有当路径两端的点属于同一连通块且颜色与朋友喜欢的不同时输出0 code #include<bits/stdc++.h> using namespace std; char s[100005]; int fa[100005]; int 阅读全文
posted @ 2024-04-02 19:37 纯粹的 阅读(42) 评论(0) 推荐(0)
摘要:原题链接 题解 dalao‘s blog 我自己的认识请看代码区 code #include<bits/stdc++.h> using namespace std; int n,Q,root,mod; int bigson[100005];//和自己在同一条链上的儿子节点 vector<int> G 阅读全文
posted @ 2024-04-03 12:25 纯粹的 阅读(33) 评论(0) 推荐(0)
摘要:原题链接 题解 树上区间修改加单点查询,虽然可以树状数组,但是线段树更通用一点 然而线段树通常处理的是点权,可这里是边权,怎么办呢?我们可以把边权转换成点权,由于每个点的子边有若干个,但父边有且只有一个,这样我们就把边权变成边下方点的点权 然后区间修改和单点求和的时候把lca的点权删掉即可 code 阅读全文
posted @ 2024-04-03 20:13 纯粹的 阅读(34) 评论(0) 推荐(0)
摘要:原题链接 题解 1.任意两点间的异或和等于他们到根节点的异或和的异或,令每个点到根节点的异或值为 \(path[i]\) 2.建立01字典树,塞入所有 \(path[i]\) 然后遍历每个点,找出每个点异或最大对应的点 3.如何找?往当前 \(path[i]\) 的每一位相反的方向移动 code # 阅读全文
posted @ 2024-04-04 15:27 纯粹的 阅读(24) 评论(0) 推荐(0)
摘要:原题链接 题解 只需要存在两个叶子节点之间距离等于d就好了,于是我们构造一条链,令节点一为滑动变阻器,则根据d改变与节点n的距离即可 code #include<bits/stdc++.h> using namespace std; int main() { int t; cin>>t; while 阅读全文
posted @ 2024-04-12 18:46 纯粹的 阅读(14) 评论(0) 推荐(0)
摘要:原题链接 题解 看清楚题目,是三个人都坐在同一辆校车!! code #include<bits/stdc++.h> #define ll long long using namespace std; vector<ll> G[200005]; ll depth[200005]={0}; void d 阅读全文
posted @ 2024-05-14 12:48 纯粹的 阅读(14) 评论(0) 推荐(0)
摘要:原题链接 题解 easy.ver::只能朝一个方向走,还剩奇数个格子时先手获胜 medium.ver: 令 \(u_i\) 为根节点,这样就只能朝子节点的方向走,设 \(dp[now]\) 为当以now为根的树,且now节点已经有一颗棋(其子节点均还没有)时,先手必胜1还是必败0,状态转移方程:\( 阅读全文
posted @ 2024-05-14 20:43 纯粹的 阅读(139) 评论(0) 推荐(0)
摘要:原题链接 题解 1.已知如果两个点之间有两条边不重合的路径,那么这两个点就在一个边强连通分量里,所以我们可以把处于同一个边强连通分量的点缩起来 在这里,我忘记了怎么求边强连通分量,所以我再提醒一下自己 已知树结构是不存在强连通分量的,它的特性是深度大的节点只有一条回到深度小的节点的边,所以我们深度搜 阅读全文
posted @ 2024-05-15 19:05 纯粹的 阅读(27) 评论(0) 推荐(0)
摘要:原题链接 题解 1.多根树结构,但是将-1的点设为0的子节点,就变成了单根树 2.仔细读题!!!只要同一链上的就不能在一个组里 code #include<bits/stdc++.h> using namespace std; int depth[2005]={0}; vector<int> G[2 阅读全文
posted @ 2024-05-15 21:16 纯粹的 阅读(29) 评论(0) 推荐(0)
摘要:原题链接 题解 很巧妙,把等式移项之后,ab差最大的就是答案 code #include<bits/stdc++.h> using namespace std; #define ll long long struct node { int a,b,df,id; }c[200005]; bool cm 阅读全文
posted @ 2024-05-16 19:27 纯粹的 阅读(23) 评论(0) 推荐(0)
摘要:原题链接 题解 真的bt啊 由于m没有限制所有测试用例的总和,所以m可以近似看为1e9,也就是说,除了输入以外,不能有任何对m的处理(常数乘上1e9) 考虑菊花图,任意两点之间最多只有一个陌生点,而且 \(m\lt n\) 所以找出那个没有出现过的中间点,作为菊花图的中心 md!!构造题!! cod 阅读全文
posted @ 2024-05-16 20:16 纯粹的 阅读(25) 评论(0) 推荐(0)
摘要:原题链接 题解 观察一个二分图会发现 同一组的节点不直接相连 二分图能够建立的最多的边等于 \(n*m\) code #include<bits/stdc++.h> using namespace std; #define ll long long vector<ll> G[100005]; ll 阅读全文
posted @ 2024-05-16 20:34 纯粹的 阅读(22) 评论(0) 推荐(0)
摘要:原题链接 题解 有点像拓扑排序 拓扑排序怎么做来着?首先找老祖节点对不对?老祖节点有什么特性? 入度为零 而在无向图中,我们把叶子节点看成老祖节点,它们有什么特性? 连接的边只有一条 code #include<bits/stdc++.h> using namespace std; vector<i 阅读全文
posted @ 2024-05-24 21:25 纯粹的 阅读(42) 评论(0) 推荐(0)
摘要:原题链接 题解 由易到难,先不考虑交替的事情,既然要尽量少的涂色,那么我最少要涂几条颜色的边?(由于图不一定联通,这里先考虑连通图的情况) 如果一条边处于一个环内,那么这个边就可以不涂色。 所以只要有环我就可以选择一条边不涂色,那么到最后,涂色的边构成一棵树 接下来考虑这颗树能否实现红蓝交替 要满足 阅读全文
posted @ 2024-05-24 21:54 纯粹的 阅读(90) 评论(0) 推荐(0)
摘要:原题链接 题解 最大深度·k-与节点1的距离·c 其中最大深度只要知道了节点1的最大深度,其子节点的最大深度可分类讨论得出 code #include<bits/stdc++.h> #define ll long long using namespace std; vector<ll> G[2000 阅读全文
posted @ 2024-06-14 14:17 纯粹的 阅读(11) 评论(0) 推荐(0)
摘要:原题链接 题解 1.观察样例易得改变是有后继性的 2.总是解题时没有思路,一点拨就有思路,怎么办? 我们要找到一些规律,即一定会发生的现象 3.当我们对一场比赛的晋级规律进行修改后,这场比赛的晋级人数取决于其先前两场比赛的晋级人数 实施 1.参考线段树,将第 \(i\) 场比赛改为id为 \(2^k 阅读全文
posted @ 2024-06-19 16:27 纯粹的 阅读(23) 评论(0) 推荐(0)
摘要:原题链接 题解 暴力:遍历所有点为根节点的情况,然后遍历子节点,统计众数,时间复杂度 \(O(n^2)\) 优化:上面的算法时间复杂度之所以为 \(O(n^2)\) 是因为算父节点时,子节点又重新算了一遍,所以我们可以在算父节点时,保留一个子树的贡献,然后其他子树的贡献暴力遍历一遍 运用重链剖分,每 阅读全文
posted @ 2024-07-12 14:23 纯粹的 阅读(21) 评论(0) 推荐(0)
摘要:原题链接 题解 1.假设有一个以标记点 \(c\) 为根的子树,且子树内没有其他标记点,易得该子树内所有点的 \(f\leq f(c)\),所以我们可以把该子树内的非标记点全部删掉 2.完成步骤1之后,图就变成了所有叶子节点均为标记点的树 3.题目等价于求该树内,最小的点到边界的最大值,也就是求树的 阅读全文
posted @ 2024-07-14 16:15 纯粹的 阅读(41) 评论(0) 推荐(0)
摘要:原题链接 题解 题目要求有多少个点,其到标记点的最远距离不超过 \(d\) 看到这个我们不难想到树的直径:设直径端点 \(a,b\),树上任意一点 \(c\) 到叶子节点的距离 \(\leq max(d(c,a),d(c,b))\) 所以,我们把标记点看成叶子节点,并找出相距最远的一对标记点 \(a 阅读全文
posted @ 2024-07-15 14:30 纯粹的 阅读(16) 评论(0) 推荐(0)
摘要:原题链接 题解 由于树上任意一点 \(c\) 到其他点的最大距离 \(= max(dis(c,a),dis(c,b))\),其中 \(ab\) 为直径,易得直径中点该值最小(其他点都要经过中点) 所以两棵树合并要使直径最短,一定是中点相连,但是因为我们只查询直径,所以不需要真的去找中点在哪,只需要维 阅读全文
posted @ 2024-07-15 14:59 纯粹的 阅读(28) 评论(0) 推荐(0)
摘要:原题链接 题解 先随便找一条直径,然后标记这些边,然后看看直径上的点有没有不需要经过标记边的路径,使得其长度等于该点到直径端点的路径长度 code #include<bits/stdc++.h> #define ll long long using namespace std; struct edg 阅读全文
posted @ 2024-07-15 17:28 纯粹的 阅读(44) 评论(0) 推荐(0)
摘要:原题链接 题意 树中任意一条路径上黑色点的数量不超过两个,请问存在多少种树 分析 先随便找一个节点作为根节点,然后分类讨论 假如根到叶子节点的路径上有两个黑色节点,则不能再添加其他点了 如果根到叶子节点的路径上有一个黑色节点,则可以还可以在不在这条路径上的地方放黑色节点 在弄清楚规则后,就可以用dp 阅读全文
posted @ 2024-07-19 21:33 纯粹的 阅读(17) 评论(0) 推荐(0)
摘要:原题链接 题解 往无向图中添加至少几条边,使得图中包含奇数环? 注意是要添加少边,而不是使环小 讨论 1.0条 当且仅当原图中存在奇环,方案数为0 用bfs染色判断,即对于一个环,bfs一定会绕一圈该环,然后黑白染色判断奇偶即可 2.一条 当且仅当存在一连通图大小大于等于3 对于该连通图内,对方案数 阅读全文
posted @ 2024-08-01 20:44 纯粹的 阅读(40) 评论(0) 推荐(0)
摘要:原题链接 获取题意 1.只能传送一次。 2.走树边没有限制。 3.只能传送至非相邻节点 4.路径一定是如下形式: \(S\to x \to T\) 其中要么 \(x\to T\) 传送要么 \(S\to x\) 传送 \(S\to x \to y \to T\) 其中 \(x\to y\) 传送 \ 阅读全文
posted @ 2024-08-07 15:34 纯粹的 阅读(59) 评论(0) 推荐(0)
摘要:原题链接 分析 考虑两个点对 \((a,b),(x,y)\) 如果点对 \((a,b)\) 的路径与点对 \((x,y)\) 的路径不存在共同的点,那么此时我们交换 \(a,x\),则有点对 \((x,b),(a,y)\) 此时两个点对的路径相交,且 \(dis(x,b)+dis(a,y)\gt d 阅读全文
posted @ 2024-08-10 15:32 纯粹的 阅读(40) 评论(0) 推荐(0)