ABC 359
A,B
直接模拟即可。
C
纵向的距离很好算。有两种情况:
-
横向距离更小。这个直接输出纵向距离。
-
更大。减去纵向的步数。
横向距离怎么算?我们考虑把
D
简单的 dp。设 A,B
分别是 A,B
可不可以。
E
直接单调栈维护目前目前的最大值们。如果有更优(即更靠后切更大)就弹出。
F
考虑到知道每一个都至少有
G
我一个很显然的数据分治(出现次数
其实这个题可以直接启发式合并。每一个节点维护每一个颜色的出现个数。可以把
这道题按道理来说虚树,点分治都可以做,但是这个应该是我见到的最简洁的写法。
Code
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 2e5+5;
int n,dep[N],a[N],fr[N];
vector<int> g[N];
map<int,int> mp[N];
ll ans;
void dfs(int u,int fa){
for (auto v : g[u]){
if (v^fa){
dep[v]=dep[u]+1;
dfs(v,u);
}
}
mp[u][a[u]]=1;
for (auto v : g[u]){
if (v^fa){
if (mp[v].size()>mp[u].size()){
swap(mp[v],mp[u]);
}
for (auto x : mp[v]){
ans-=1ll*x.second*mp[u][x.first]*dep[u]*2ll;
mp[u][x.first]+=x.second;
}
}
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n;
for (int i=1; i<n; i++){
ll u,v;
cin>>u>>v;
g[u].push_back(v);
g[v].push_back(u);
}
for (int i=1; i<=n; i++){
cin>>a[i];
fr[a[i]]++;
}
dfs(1,0);
for (int i=1; i<=n; i++){
ans+=1ll*(fr[a[i]]-1)*dep[i];
}
cout<<ans<<"\n";
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具