Submission #1199500

#TimeUsernameProblemLanguageResultExecution timeMemory
1199500cxijsijsjsykTeam Coding (EGOI24_teamcoding)C++20
81 / 100
4030 ms51660 KiB
#include<iostream>
#include<vector>
#include<algorithm>
#include<map>
#include<cmath>
#include<cassert>
using namespace std;
vector<int> edges[100005];
pair<int, int> times[100005];
int depth[100005];
int col[100005]; int cnt = 1;
vector<int> depthtimes[100005];
vector<int> nwcol[100005];
map<int, int> dwcol[100005];
map<int, int> stdepth; map<int, int> cldepth;
int bestans = 0; int bestswap = 1e9;

void dfs(int n, int d) {
	times[n].first = cnt++;
	depth[n] = d;
	for (auto c : edges[n]) {
		dfs(c, d+1);
	}
	times[n].second = cnt++;
}

void find(int n, int cl, bool found) {
	if (found) {
		stdepth[depth[n]]++;
		if (col[n] == cl) cldepth[depth[n]]++;
	}
	for (auto c : edges[n]) {
		if (col[n] == cl) find(c, cl, true);
		else find(c, cl, found);	
	}
	if (col[n] == cl && !found) {
		int curans = 0; int curswap = 0;
		for (auto p : stdepth) {
			curans += min(p.second, dwcol[cl][p.first]);
			curswap += max(0, min(p.second, dwcol[cl][p.first])-cldepth[p.first]);
		}
		if (bestans == curans+1) {
			bestswap = min(bestswap, curswap);
		}
		else if (bestans < curans+1) {
			bestans = curans+1;
			bestswap = curswap;
		}
		stdepth.clear(); cldepth.clear();
	}
}
int most[100005];
int main() {
	int n, k; cin>>n>>k;
	for (int i = 0; i < n; i++) {
		cin>>col[i];
		most[col[i]]++;
	}
	for (int i = 1; i < n; i++) {
		int x; cin>>x;
		edges[x].push_back(i);
	}
	
	dfs(0, 0);

	for (int i = 0; i < n; i++) {
		dwcol[col[i]][depth[i]]++;
	}
		

	for (int i = 0; i < n; i++) {
		depthtimes[depth[i]].push_back(times[i].first);
	}
	for (int i = 0; i <= n; i++) {
		sort(depthtimes[i].begin(), depthtimes[i].end());
	}
	for (int i = 0; i < n; i++) {
		nwcol[col[i]].push_back(i);
	}
		
	for (int clr = 0; clr < k; clr++) {
		if (most[clr] >= sqrt(n)) {
			find(0, clr, false);
		}
		else {
			for (int z = 0; z < nwcol[clr].size(); z++) {
				int i = nwcol[clr][z];
				map<int, int> used;
				map<int, int> swapped;
				int curans = 0;
				int curswap = 0;
				for (auto j : nwcol[col[i]]) {
					//cout<<nwcol[col[i]].size()<<endl;
					if (j == i || depth[j] <= depth[i]) continue;
					int up = upper_bound(depthtimes[depth[j]].begin(), depthtimes[depth[j]].end(), times[i].second)-depthtimes[depth[j]].begin();
					int low = lower_bound(depthtimes[depth[j]].begin(), depthtimes[depth[j]].end(), times[i].first)-depthtimes[depth[j]].begin();
					if (up-low-used[depth[j]]>0) {
						used[depth[j]]++;
						curans++;
						swapped[depth[j]]++;
						curswap++;
					}
					if (times[i].first < times[j].first && times[j].second < times[i].second) {
						if (swapped[depth[j]]>0) {
							swapped[depth[j]]--;
							curswap--;	
						}
					}
				}
				if (bestans == curans+1) {
					bestswap = min(bestswap, curswap);
				}
				else if (bestans < curans+1) {
					bestans = curans+1;
					bestswap = curswap;
				}
				
		
			}
		}
	}
	cout<<bestans<<" "<<bestswap<<endl;
} 
#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...