#include <bits/stdc++.h>
//#include "includeall.h"
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
#define endl '\n'
#define f first
#define s second
#define pb push_back
#define mp make_pair
#define lb lower_bound
#define ub upper_bound
#define input(x) scanf("%lld", &x);
#define input2(x, y) scanf("%lld%lld", &x, &y);
#define input3(x, y, z) scanf("%lld%lld%lld", &x, &y, &z);
#define input4(x, y, z, a) scanf("%lld%lld%lld%lld", &x, &y, &z, &a);
#define print(x, y) printf("%lld%c", x, y);
#define show(x) cerr << #x << " is " << x << endl;
#define show2(x,y) cerr << #x << " is " << x << " " << #y << " is " << y << endl;
#define show3(x,y,z) cerr << #x << " is " << x << " " << #y << " is " << y << " " << #z << " is " << z << endl;
#define all(x) x.begin(), x.end()
#define discretize(x) sort(x.begin(), x.end()); x.erase(unique(x.begin(), x.end()), x.end());
#define FOR(i, x, n) for (ll i =x; i<=n; ++i) 
#define RFOR(i, x, n) for (ll i =x; i>=n; --i) 
using namespace std;
mt19937_64 rnd(chrono::steady_clock::now().time_since_epoch().count());
//using namespace __gnu_pbds;
//#define ordered_set tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update>
//#define ordered_multiset tree<int, null_type, less_equal<int>, rb_tree_tag, tree_order_statistics_node_update>
typedef int ll;
typedef long double ld;
typedef pair<ld, ll> pd;
typedef pair<string, ll> psl;
typedef pair<ll, ll> pi;
typedef pair<pi, ll> pii;
typedef pair<pi, pi> piii;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
ll const blk = 1000;
ll n, k, label = 0;
ll color[100005], par[100005], in[100005], out[100005], cnt[100005], dep[100005], big[100005];
vector<ll> adj[100005], nodelist[100005];
unordered_map<ll, ll> dp[100005], dp2[100005], dp3[100005], dp4[100005], dp5[100005], col[100005];
unordered_set<ll> deplist[100005];
pi ans = mp(-1e9, -1e9);
void precomp1(ll x = 0)
{
	in[x] = ++label;
	for (ll u: adj[x]) 
	{
		dep[u] = dep[x] + 1;
		precomp1(u);
	}
	out[x] = label;
	deplist[color[x]].insert(dep[x]);
}
void precomp2(ll x = 0)
{
	col[color[x]][dep[x]]++;
	for (ll u: adj[x]) 
	{
		precomp2(u);
		if (dp[x].size() < dp[u].size()) swap(dp[u], dp[x]);
		for (pi u: dp[u]) dp[x][u.f] += u.s;
	}
	dp[x][dep[x]]++;
	if (!big[x]) for (ll u: deplist[color[x]]) dp2[x][u] += dp[x][u];
}
void dfs(ll x, ll c, ll yes = 1)
{
	//show2(x, yes);
	for (ll u: adj[x]) 
	{
		dfs(u, c, yes&ll(color[x]!=c));
		if (dp4[x].size() < dp4[u].size()) swap(dp4[u], dp4[x]);
		for (pi v: dp4[u]) dp4[x][v.f] += v.s;
		if (dp5[x].size() < dp5[u].size()) swap(dp5[u], dp5[x]);
		for (pi v: dp5[u]) dp5[x][v.f] += v.s;
		
	}
	if (yes && color[x]==c)
	{
		//show(x);
		ll res = 0, res2 = 0;
		for (ll u: deplist[c])
		{
			if (u <= dep[x]) continue;
			//show3(u, dp4[x][u], col[c][u]);
			ll take = min(dp4[x][u], col[c][u]);
			res += take;
			res2 +=  max(0, take - dp5[x][u]);
		}
		//show2(res, res2);
		ans = max(ans, mp(res, -res2));
	}
	dp4[x][dep[x]]++;
	if (c==color[x]) dp5[x][dep[x]]++;
}
void solve(ll c)
{
	//for (ll u: nodelist[c]) show(u);
	for (ll i=0; i<nodelist[c].size(); ++i)
	{
		for (ll j=i + 1; j<nodelist[c].size(); ++j)
		{
			ll x = nodelist[c][i], y = nodelist[c][j];
			if (in[x] > in[y]) swap(x, y);
			if (in[x] <= in[y] && in[y] <= out[x]) dp3[x][dep[y]]++;
		}
	}
	for (ll i=0; i<nodelist[c].size(); ++i)
	{
		ll res = 0, res2 = 0, x = nodelist[c][i];
		//show(x);
		for (ll u: deplist[c])
		{
			if (u <= dep[x]) continue;
			//show(u);
			ll take = min(dp2[x][u], col[c][u]);
			res += take;
			res2 += max(0, take - dp3[x][u]);
		}
		ans = max(ans, mp(res, -res2));
	}
}
int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	cin >> n >> k;
	for (ll i=0; i<n; ++i) {cin >> color[i]; cnt[color[i]]++; nodelist[color[i]].pb(i); }
	for (ll i=0; i<k; ++i) if (cnt[i] > blk) big[i] = 1;
	for (ll i=1; i<n; ++i) {cin >> par[i];  adj[par[i]].pb(i);}
	precomp1(); precomp2();
	for (ll i=0; i<k; ++i)
	{
		//show("start");
		//show(i);
		if (big[i]) 
		{
			for (ll j=0; j<n; ++j) {dp5[j].clear(); dp4[j].clear();}
			dfs(0, i, 1);
		}
		else {solve(i);}
	}
	cout << ans.f + 1 << ' ' << -ans.s << endl;
	return 0;
}
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... |