Submission #1340807

#TimeUsernameProblemLanguageResultExecution timeMemory
1340807WH8Team Coding (EGOI24_teamcoding)C++17
100 / 100
3301 ms42696 KiB
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>
using namespace std;
using namespace __gnu_pbds;
#define g0(x) get<0>(x)
#define g1(x) get<1>(x)
#define g2(x) get<2>(x)
#define mt make_tuple
#define mp make_pair
#define pb push_back
#define int long long 
#define f first
#define s second
#define pll pair<long long, long long>
#define iii tuple<int,int,int>
#define sz(x) (int)x.size()
#define all(x) x.begin(), x.end()

const int blk=305;
signed main(){
	int n,k;cin>>n>>k;
	vector<int> c(n); for(int i=0;i<n;i++)cin>>c[i];
	vector<vector<int>> grp(n);
	vector<int> pre(n, 0), post(n, 0), lay(n, 0);
	vector<vector<int>> layer(n);
	vector<vector<int>> ch(n);
	for(int i=1;i<n;i++){
		int b;cin>>b;
		ch[b].pb(i);
	}
	int t=0;
	auto dfs=[&](auto && dfs, int x) -> void{
		pre[x]=t++;
		layer[lay[x]].pb(pre[x]);
		grp[c[x]].pb(x);
		for(auto it: ch[x]){
			lay[it]=lay[x]+1;
			dfs(dfs, it);
		}
		post[x]=t-1;
	};
	dfs(dfs, 0);
	pair<int,int> ans={0, 0};
	for (int i=0;i<n;i++){
		if(sz(grp[i]) < blk){
			map<int,int> tot;
			for(int j : grp[i]){
				tot[lay[j]]++;
			}
			/*for (auto [l, totcnt] : tot){
				printf("col %lld, layer %lld, cnt %lld\n", i, l, totcnt);
			}*/
			for(int j : grp[i]){
				map<int,int> und;
				for(int k : grp[i]){
					if(pre[j] <= pre[k] and post[j] >= pre[k]){
						und[lay[k]]++;
					}
				}
				pll cand={0, 0};
				for(auto [l, totcnt] : tot){
					int undcnt=und[l];
					int sl=upper_bound(all(layer[l]), post[j])-lower_bound(all(layer[l]), pre[j]);
					//printf("parent %lld, l %lld, totcnt %lld, sl %lld\n", j, l, totcnt, sl);
					int u=min(sl, totcnt);
					int cost=u-und[l];
					cand.f += u, cand.s += cost;
				}
				if(cand.f > ans.f or (cand.f == ans.f and cand.s < ans.s)) ans=cand;
			}
		}
		else {
			vector<int> stk, heads;
			map<int,int> tot;
			for(int j : grp[i]){
				tot[lay[j]]++;
			}
			/*for (auto [l, totcnt] : tot){
				printf("col %lld, layer %lld, cnt %lld\n", i, l, totcnt);
			}*/
			for(int j : grp[i]){
				while(!stk.empty() and post[stk.back()] < pre[j]){
					stk.pop_back();
				}
				if(stk.empty()){
					heads.pb(j);
					stk.pb(j);
				}
			}
			for(int j : heads){
				//printf("col %lld, head j %lld\n", i, j);
				map<int, int> slays, und;
				auto dfs2=[&](auto && dfs2, int x)->void{
					slays[lay[x]]++;
					if(c[x] == i) und[lay[x]]++;
					for(auto it : ch[x]){
						dfs2(dfs2, it);
					}
				};
				dfs2(dfs2, j);
				pll cand={0, 0};
				for(auto [l, sl]: slays){
					int undcnt=und[l];
					int totcnt=tot[l];
					int u=min(sl, totcnt);
					int cost=u-und[l];
					cand.f += u, cand.s += cost;
					//printf("layer %lld, sl %lld, undcnt %lld, totcnt %lld, u %lld, cost %lld\n", 
					//l, sl, undcnt, totcnt, u, cost);
				}
				if(cand.f > ans.f or (cand.f == ans.f and cand.s < ans.s)) ans=cand;
			}
		}
	}
	cout<<ans.f<<" "<<ans.s;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...