洛谷 P2971 [USACO10HOL] Cow Politics G 题解
怎么没有树上启发式合并的题解呢?我来发一篇吧!
简化题意
给定一棵 \(n\) 个点的树,每个点属于 \(k\) 种颜色之一(每种颜色至少有 2 个点)。求每种颜色中,任意两点间的最大距离。
核心思想
树上两点 \(u,v\) 间的距离为 \(dep_u+dep_v-2×dep_{lca(u,v)}\)。同色节点中的最大距离一定对应其中两个节点。考虑枚举它们的 LCA。
对每个节点 \(u\),若它作为 LCA,则考虑它的所有子树中的同色节点,计算不同子树中的同色节点间的最大距离并更新答案。
算法步骤
使用树上启发式合并,维护每种颜色的深度集合。
- 预处理:计算每个点的深度、子树大小、重儿子,和以它为根子树的 DFS 序区间。
- 启发式合并:
- 处理轻子树,处理后从集合中删除其节点。
- 处理重子树。
- 对每个轻子树,计算其节点与已处理节点的同色最大距离并更新答案,再将其加入集合。
- 将当前节点自身当作一棵轻子树处理。
数据结构
对于每种颜色都开一个动态开点平衡树 multiset 维护这种颜色的节点的深度,支持插入、删除和查询最大值。由于深度可能有重复,因此不能用 set。
复杂度分析
对于时间复杂度,每个节点都会被操作 \(O(\log n)\) 次,每次操作 \(O(\log n)\)。一共 \(n\) 个节点。因此总时间复杂度为 \(O(n \log^2 n)\),可以通过本题数据。
对于空间复杂度,由于所有 multiset 中最多保存 \(n\) 个节点的深度,再加上其他长度为 \(n\) 的数组,总空间复杂度为 \(O(n)\)。
AC Code
#include <bits/stdc++.h>
#define rept(i,a,b) for(int i(a);i<=b;++i)
#define eb emplace_back
using namespace std;
constexpr int N=2e5+5,K=1e5+5;
multiset<int> s[K];
vector<int> g[N];
int id[N],dep[N],l[N],r[N],siz[N],ch[N],a[N],ans[K],tot;
void dfs(int u,int pre){
siz[u]=1,l[u]=++tot,id[tot]=u;
for(int v:g[u]){
if(v==pre) continue;
dep[v]=dep[u]+1;
dfs(v,u);
siz[u]+=siz[v];
if(siz[v]>siz[ch[u]]) ch[u]=v;
}
r[u]=tot;
}
void add(int l,int r){ // 插入一棵子树
rept(i,l,r){
int u=id[i];
s[a[u]].insert(dep[u]);
}
}
void sub(int l,int r){ // 删除一棵子树
rept(i,l,r){
int u=id[i];
// 坑点:如果用s[a[u]].erase(dep[u])则会删除所有等于dep[u]的元素,并不是只删一个
s[a[u]].erase(s[a[u]].find(dep[u]));
}
}
void calc(int l,int r,int lca){ // 更新答案
rept(i,l,r){
int u=id[i];
if(s[a[u]].empty()) continue;
int d=*s[a[u]].rbegin();
ans[a[u]]=max(ans[a[u]],d+dep[u]-(dep[lca]<<1));
}
}
void dsu(int u,int pre){
for(int v:g[u]){ // 处理轻儿子
if(v==pre||v==ch[u]) continue;
dsu(v,u);
sub(l[v],r[v]);
}
if(ch[u]) dsu(ch[u],u); // 重儿子
for(int v:g[u]){
if(v==pre||v==ch[u]) continue;
calc(l[v],r[v],u);
add(l[v],r[v]);
}
// 处理这个节点本身
calc(l[u],l[u],u);
add(l[u],l[u]);
}
int main(){
cin.tie(0)->sync_with_stdio(0);
int n,k,t;
cin>>n>>k;
rept(i,1,n){
cin>>a[i]>>t;
if(t) g[i].eb(t),g[t].eb(i);
}
dfs(1,0);
dsu(1,0);
rept(i,1,k){
cout<<ans[i]<<'\n';
}
return 0;
}
洛谷 P2971 [USACO10HOL] Cow Politics G 题解的更多相关文章
- 洛谷P2886 [USACO07NOV]Cow Relays G (矩阵乘法与路径问题)
本题就是求两点间只经过n条边的最短路径,定义广义的矩阵乘法,就是把普通的矩阵乘法从求和改成了取最小值,把内部相乘改成了相加. 代码包含三个内容:广义矩阵乘法,矩阵快速幂,离散化: 1 #include ...
- 洛谷P1854 花店橱窗布置 分析+题解代码
洛谷P1854 花店橱窗布置 分析+题解代码 蒟蒻的第一道提高+/省选-,纪念一下. 题目描述: 某花店现有F束花,每一束花的品种都不一样,同时至少有同样数量的花瓶,被按顺序摆成一行,花瓶的位置是固定 ...
- HAOI2006 (洛谷P2341)受欢迎的牛 题解
HAOI2006 (洛谷P2341)受欢迎的牛 题解 题目描述 友情链接原题 每头奶牛都梦想成为牛棚里的明星.被所有奶牛喜欢的奶牛就是一头明星奶牛.所有奶 牛都是自恋狂,每头奶牛总是喜欢自己的.奶牛之 ...
- 洛谷P3412 仓鼠找$Sugar\ II$题解(期望+统计论?)
洛谷P3412 仓鼠找\(Sugar\ II\)题解(期望+统计论?) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1327573 原题链接:洛谷P3412 ...
- 洛谷P3502 [POI2010]CHO-Hamsters感想及题解(图论+字符串+矩阵加速$dp\&Floyd$)
洛谷P3502 [POI2010]CHO-Hamsters感想及题解(图论+字符串+矩阵加速\(dp\&Floyd\)) 标签:题解 阅读体验:https://zybuluo.com/Junl ...
- LCA【洛谷P2971】 [USACO10HOL]牛的政治Cow Politics
P2971 [USACO10HOL]牛的政治Cow Politics 农夫约翰的奶牛住在N (2 <= N <= 200,000)片不同的草地上,标号为1到N.恰好有N-1条单位长度的双向 ...
- 不失一般性和快捷性地判定决策单调(洛谷P1912 [NOI2009]诗人小G)(动态规划,决策单调性,单调队列)
洛谷题目传送门 闲话 看完洛谷larryzhong巨佬的题解,蒟蒻一脸懵逼 如果哪年NOI(放心我这样的蒟蒻是去不了的)又来个决策单调性优化DP,那蒟蒻是不是会看都看不出来直接爆\(0\)?! 还是要 ...
- 洛谷2973 [USACO10HOL]赶小猪Driving Out the Piggi… 概率 高斯消元
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - 洛谷2973 题意概括 有N个城市,M条双向道路组成的地图,城市标号为1到N.“西瓜炸弹”放在1号城市,保证城 ...
- BZOJ4946 & 洛谷3826 & UOJ318:[NOI2017]蔬菜——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=4946 https://www.luogu.org/problemnew/show/P3826 ht ...
- 洛谷P1972 [SDOI2009]HH的项链 题解
[SDOI2009]HH的项链 题目背景 无 题目描述 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义.HH 不 ...
随机推荐
- 从Clipto.AI看AI SaaS创业的隐形机会:一个月2500万访问量背后的商业逻辑
最近深度研究了一个让我眼前一亮的产品--Clipto.AI. 这款看似简单的音视频转录工具,月访问量竟然达到了2540万,这个数字让我震惊,也让我重新思考了AI工具的商业化路径. 今天想和大家分享一下 ...
- 如何通过Cgroups机制实现资源限制?
1.什么是Cgroups? 在说Cgroups之前,我们先说说容器的"限制"问题. 我们知道通过Linux Namespace技术,可以实现容器中的进程看不到别的容器资源,但是有一 ...
- python基础—数字,字符串练习题
1.如有以下变量 n1=5,请使用 int 的提供的方法,得到该变量最少可以用多少个二进制位表示? n1=5 r=n1.bit_lenght() #当前数字的二进制,至少用n位表示.bit_lengh ...
- Springboot笔记<8>异常处理 文件上传
文件上传 springboot可以直接使用 org.springframework.web.multipart.MultipartFile实现文件上传功能. 1.创建form表单: <!DOCT ...
- 你应该懂的AI大模型(一) 之 浅知大模型
1.AI 大模型的训练过程 AI 大模型的训练就如同让一名孩童从不会说话一步步培养成高级知识分子或者专家的过程. 第一步:收集数据,将海量的知识与文章收集起来作为学习资料教给这个孩子: 第二步:预处理 ...
- 江铃晶马 X 袋鼠云:搭建企业级数据资产中心,推进打造“智数晶马”
江铃集团晶马汽车有限公司(简称:晶马汽车)系江铃集团全资子公司,属集团六大整车企业之一.晶马汽车是以大.中.轻型客车(含新能源客车).乘用车(不含轿车).专用车等车型研发.生产.销售和服务为核心的整车 ...
- Blazor学习之旅(4)数据共享
本篇,我们来了解下在Blazor中数据是如何共享的,组件之间又该如何传递参数. 关于Blazor组件 在 Blazor 中,从名为"组件"的自包含代码部分生成 UI.每个组件都可以 ...
- C# WinForm 中让panel 可以在WinForm 中移动
panelContent.MouseDown += Panel_MouseDown; // 为Panel添加鼠标移动事件处理程序 panelContent.MouseMove += Panel_Mou ...
- 多Agent协作入门:并发编排模式
大家好,我是Edison. 上一篇我们学习了Semantic Kernel中的AgentGroupChat实现群聊的效果,但其实多Agent协作编排还有一些其他的模式.今天就来和你唠唠其他支持的编排模 ...
- Day13 备战CCF-CSP练习
Day 13 题目描述 题目分析 大模拟,用栈储存每一个多项式,最后根据导数的加法原则依次求导相加,注意取模. C++代码 #pragma GCC optimize(3, "Ofast&qu ...