Submission #1300603

#TimeUsernameProblemLanguageResultExecution timeMemory
1300603PieArmyTeam Coding (EGOI24_teamcoding)C++20
58 / 100
68 ms26120 KiB
#include<bits/stdc++.h>
typedef long long ll;
#define pb push_back
#define fr first
#define sc second
#define endl '\n'
using namespace std;
#define mid ((left+right)>>1)

int s=317;
int n,k;
int arr[100023];
vector<int>renk[100023],deps[100023];
vector<int>child[100023];
int in[100023],out[100023];
int dep[100023],h[100023];
int tim=0;
pair<int,int>res[100023];
pair<int,int>ans;

void dfs(int pos){
	in[pos]=++tim;
	deps[dep[pos]].pb(pos);
	for(int x:child[pos]){
		dep[x]=dep[pos]+1;
		dfs(x);
		h[pos]=max(h[pos],h[x]+1);
	}
	out[pos]=tim;
}

int main(){
	ios_base::sync_with_stdio(23^23);cin.tie(NULL);
	cin>>n>>k;
	ans={-1,0};
	for(int i=1;i<=n;i++){
		res[i]={-1,0};
		cin>>arr[i];
		arr[i]++;
		renk[arr[i]].pb(i);
	}
	for(int i=2;i<=n;i++){
		int x;cin>>x;x++;
		child[x].pb(i);
	}
	dfs(1);
	for(int o=1;o<=k;o++){
		if(!renk[o].size())continue;
		if(renk[o].size()>s){
			sort(renk[o].begin(),renk[o].end(),[&](const int &x,const int &y){
				return in[x]<in[y];
			});
			vector<int>roots;
			vector<int>pot;
			int mxout=0;
			for(int x:renk[o]){
				if(in[x]>mxout){
					pot.pb(x);
				}
				mxout=max(mxout,out[x]);
			}
			sort(pot.begin(),pot.end(),[&](const int &x,const int &y){
				return dep[x]+h[x]<dep[y]+h[y];
			});
			for(int i=n-1;i>0;i--){
				vector<int>roots2;
				for(int j=0;j<roots.size();j++){
					int x=roots[j];
					if(dep[x]<i)roots2.pb(x);
				}
				swap(roots,roots2);
				int cnt=0;
				vector<int>v;
				for(int x:deps[i]){
					if(arr[x]==o){
						cnt++;
						v.pb(x);
					}
				}
				while(pot.size()&&dep[pot.back()]+h[pot.back()]>=i){
					roots.pb(pot.back());
					pot.pop_back();
				}
				for(int j=0;j<roots.size();j++){
					int var=0;
					int top=0;
					int l2=0,r2=deps[i].size();
					while(l2<r2){
						int mi=(l2+r2)/2;
						int x=deps[i][mi];
						if(in[x]>=in[roots[j]])r2=mi;
						else l2=mi+1;
					}
					top-=l2;
					l2=0;r2=deps[i].size();
					while(l2<r2){
						int mi=(l2+r2)/2;
						int x=deps[i][mi];
						if(in[x]>out[roots[j]])r2=mi;
						else l2=mi+1;
					}
					top+=l2;
					l2=0;r2=v.size();
					while(l2<r2){
						int mi=(l2+r2)/2;
						int x=v[mi];
						if(in[x]>=in[roots[j]])r2=mi;
						else l2=mi+1;
					}
					var-=l2;
					l2=0;r2=v.size();
					while(l2<r2){
						int mi=(l2+r2)/2;
						int x=v[mi];
						if(in[x]>out[roots[j]])r2=mi;
						else l2=mi+1;
					}
					var+=l2;
					res[roots[j]].fr-=min(top,cnt);
					res[roots[j]].sc+=max(0,min(top-var,cnt-var));
					ans=min(ans,res[roots[j]]);
				}
			}
		}
		else{
			sort(renk[o].begin(),renk[o].end(),[&](const int &x,const int &y){
				return dep[x]<dep[y];
			});
			vector<int>v;
			for(int i=0;i<renk[o].size();i++){
				for(int j=i+1;j<renk[o].size();j++){
					if(dep[renk[o][j]]<=dep[renk[o][i]])continue;
					v.pb(renk[o][j]);
					if(j+1==renk[o].size()||dep[renk[o][j+1]]!=dep[renk[o][j]]){
						int var=0,top=0;
						int cnt=v.size();
						for(int x:v){
							if(in[x]>=in[renk[o][i]]&&in[x]<=out[renk[o][i]])var++;
						}
						int l=0,r=deps[dep[v.back()]].size();
						while(l<r){
							int mi=(l+r)/2;
							int x=deps[dep[v.back()]][mi];
							if(in[x]>=in[renk[o][i]])r=mi;
							else l=mi+1;
						}
						top-=l;
						l=0;r=deps[dep[v.back()]].size();
						while(l<r){
							int mi=(l+r)/2;
							int x=deps[dep[v.back()]][mi];
							if(in[x]>out[renk[o][i]])r=mi;
							else l=mi+1;
						}
						top+=l;
						res[renk[o][i]].fr-=min(top,cnt);
						res[renk[o][i]].sc+=max(0,min(top-var,cnt-var));
						v.clear();
					}
				}
				//cout<<renk[o][i]<<": "<<-res[renk[o][i]].fr<<" "<<res[renk[o][i]].sc<<endl;
				ans=min(ans,res[renk[o][i]]);
			}
		}
	}
	cout<<-ans.fr<<" "<<ans.sc<<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...