我这里的DP数组维护的是最少修改的次数
贪心的策略是每次先加所有子树个数,然后再减去子树所有颜色的个数最大值再+1;
发现这里需要有合并操作,所以时间复杂度满足nloglog的话,可以直接上set维护,好写
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+7;
#define debug(x) cout<<"! "<<x<<endl;
#define pb push_back
typedef long long ll;
ll col[N],dp[N];
vector<int>E[N];
multiset<int>s[N];
void dfs(int u){
if(!E[u].size()){
s[u].insert(col[u]);
dp[u]=1;
return;
}
int mx=1;
for(auto v:E[u]){
dfs(v);
dp[u]+=dp[v];
if(s[u].size()<s[v].size()) swap(s[u],s[v]);
for(auto t:s[v]){
s[u].insert(t);
mx=max(mx,(int)s[u].count(t));
}
}
multiset<int>ss;
if(mx>1){
for(auto v:s[u]){
if(s[u].count(v)==mx&&!ss.count(v))
ss.insert(v);
}
swap(s[u],ss);
}
dp[u]=dp[u]-mx+1;
}
int main(){
ios::sync_with_stdio(false);cin.tie(0);
int n;cin>>n;
for(int i=2;i<=n;i++){
int x;cin>>x;
E[x].pb(i);
}
for(int i=1;i<=n;i++)
cin>>col[i];
dfs(1);
// for(int i=1;i<=n;i++)
// cout<<s[i].size()<<" ";
// cout<<'\n';
cout<<dp[1]<<'\n';
}