合集-树论
摘要:原题链接 WARNING!!! 使用map代替数组不再可靠,因为map的插入查找修改复杂度均为 ,即使unorder_map也不行!!! 题解 我们发现,当一个节点的深度之和已知时(这里认为是根节点),其相邻节点的深度之和也可通过某种方程转移而得,有人称这种方法为换根DP 具
阅读全文
摘要:原题链接 题解 请看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
阅读全文
摘要:原题链接 题解 1.具体去考虑每个集合所包含的元素及其大小个数是非常繁琐的,所以我们考虑每个元素对答案的贡献 2. 令 代表以 为根节点的答案 代表以 为根节点所包含集合的个数 更新过程如下: \(f[now]+=f
阅读全文
摘要:原题链接 题解 1.该题等价于构建一颗k叉树,每个叶子节点都有一个权值 ,树的权值为 ,在使树的权值尽可能小的情况下,使最深的叶子节点的深度也尽可能小,即使数的高度尽可能小 这个叫做哈夫曼树 2.构建过程如下:每次从队列中取出 \(
阅读全文
摘要:原题链接 题解 1.建议去B站上看看动画演示,你就明白怎么回事了 2.如何用代码实现呢?看完你就明白了 code #include<bits/stdc++.h> using namespace std; int num=0; int tree[3000006][75]={0}; int cnt[30
阅读全文
摘要:原题链接 题解 1.由于我刚刚才学字典树,所以我会告诉你这就类似字典树,对字符串终点节点加一,然后搜索统计最大前缀和 code #include<bits/stdc++.h> using namespace std; string s; int tree[2000005][65]={0}; int
阅读全文
摘要:原题链接 题解 1.修改树上某一段路径 ,最后问你单个点的最大值,很想区间修改,单点查询,且只查询一遍,所以我们往前缀和方向靠 2.一个节点只有一个父亲,所以从底到根的路径是一条链,我们可以在这里应用前缀和,标记策略为令 代表 节点到根节点这条链上所有
阅读全文
摘要:原题链接 题解 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
阅读全文
摘要:原题链接 题解 1.这k个城市一定是连成一团在中间的 2.把树展开,变成散发图,剩下的n-k个城市一定在最边缘的位置 3.拓扑排序 dalao's blog code #include<bits/stdc++.h> using namespace std; vector<int> G[100005]
阅读全文
摘要:原题链接 题解 树上只有两种颜色,我们把每种颜色的连通块记录下来,只有当路径两端的点属于同一连通块且颜色与朋友喜欢的不同时输出0 code #include<bits/stdc++.h> using namespace std; char s[100005]; int fa[100005]; int
阅读全文
摘要:原题链接 题解 dalao‘s blog 我自己的认识请看代码区 code #include<bits/stdc++.h> using namespace std; int n,Q,root,mod; int bigson[100005];//和自己在同一条链上的儿子节点 vector<int> G
阅读全文
摘要:原题链接 题解 树上区间修改加单点查询,虽然可以树状数组,但是线段树更通用一点 然而线段树通常处理的是点权,可这里是边权,怎么办呢?我们可以把边权转换成点权,由于每个点的子边有若干个,但父边有且只有一个,这样我们就把边权变成边下方点的点权 然后区间修改和单点求和的时候把lca的点权删掉即可 code
阅读全文
摘要:原题链接 题解 1.任意两点间的异或和等于他们到根节点的异或和的异或,令每个点到根节点的异或值为 2.建立01字典树,塞入所有 然后遍历每个点,找出每个点异或最大对应的点 3.如何找?往当前 的每一位相反的方向移动 code #
阅读全文
摘要:原题链接 题解 只需要存在两个叶子节点之间距离等于d就好了,于是我们构造一条链,令节点一为滑动变阻器,则根据d改变与节点n的距离即可 code #include<bits/stdc++.h> using namespace std; int main() { int t; cin>>t; while
阅读全文
摘要:原题链接 题解 看清楚题目,是三个人都坐在同一辆校车!! code #include<bits/stdc++.h> #define ll long long using namespace std; vector<ll> G[200005]; ll depth[200005]={0}; void d
阅读全文
摘要:原题链接 题解 easy.ver::只能朝一个方向走,还剩奇数个格子时先手获胜 medium.ver: 令 为根节点,这样就只能朝子节点的方向走,设 为当以now为根的树,且now节点已经有一颗棋(其子节点均还没有)时,先手必胜1还是必败0,状态转移方程:\(
阅读全文
摘要:原题链接 题解 1.已知如果两个点之间有两条边不重合的路径,那么这两个点就在一个边强连通分量里,所以我们可以把处于同一个边强连通分量的点缩起来 在这里,我忘记了怎么求边强连通分量,所以我再提醒一下自己 已知树结构是不存在强连通分量的,它的特性是深度大的节点只有一条回到深度小的节点的边,所以我们深度搜
阅读全文
摘要:原题链接 题解 1.多根树结构,但是将-1的点设为0的子节点,就变成了单根树 2.仔细读题!!!只要同一链上的就不能在一个组里 code #include<bits/stdc++.h> using namespace std; int depth[2005]={0}; vector<int> G[2
阅读全文
摘要:原题链接 题解 很巧妙,把等式移项之后,ab差最大的就是答案 code #include<bits/stdc++.h> using namespace std; #define ll long long struct node { int a,b,df,id; }c[200005]; bool cm
阅读全文
摘要:原题链接 题解 真的bt啊 由于m没有限制所有测试用例的总和,所以m可以近似看为1e9,也就是说,除了输入以外,不能有任何对m的处理(常数乘上1e9) 考虑菊花图,任意两点之间最多只有一个陌生点,而且 所以找出那个没有出现过的中间点,作为菊花图的中心 md!!构造题!! cod
阅读全文