Submission #1205397

#TimeUsernameProblemLanguageResultExecution timeMemory
1205397AbitoHighway Tolls (IOI18_highway)C++20
0 / 100
234 ms327680 KiB
#include "highway.h"
#include <bits/stdc++.h>
#define pb push_back
#define ppb pop_back
#define F first
#define S second
#define ll long long
#define elif else if
using namespace std;
const int NN=1e5;
vector<int> w;
vector<pair<int,int>> adj[NN];
int n,m,sz[NN],dep[NN],mxdep[NN],p[NN];
bool vis[NN];
ll dis;
bool cmp(pair<int,int> x,pair<int,int> y){
	return sz[x.F]<sz[y.F];
}
void getsz(int x,int par){
	sz[x]=1;
	for (auto u:adj[x]){
		if (vis[u.F] || u.F==par) continue;
		getsz(u.F,x);
		sz[x]+=sz[u.F];
	}return;
}
int get_centroid(int x,int cursz,int par){
	for (auto u:adj[x]){
		if (vis[u.F] || u.F==par) continue;
		if (sz[u.F]*2>cursz) return get_centroid(u.F,cursz,x);
	}return x;
}
void dfs(int x,int par){
	for (auto u:adj[x]){
		if (vis[u.F] || u.F==par) continue;
		w[u.S]=1;
		dfs(u.F,x);
	}return;
}
int centroid_decomposition(int x){
	getsz(x,-1);
	if (sz[x]<=2) return x;
	int centroid=get_centroid(x,sz[x],-1);
	getsz(centroid,-1);
	//cout<<centroid<<endl;
	sort(adj[centroid].begin(),adj[centroid].end(),cmp);
	int sum=0;
	for (int i=0;i<m;i++) w[i]=0;
	for (auto u:adj[centroid]){
		if (vis[u.F]) continue;
		if (2*(sum+sz[u.F])>sz[centroid]) break;
		sum+=sz[u.F];
		//cout<<u.F<<' ';
		w[u.S]=1;
		dfs(u.F,centroid);
	}//cout<<endl;
	ll h=ask(w);
	//cout<<h<<endl;
	//for (auto u:w) cout<<u;cout<<endl;
	for (auto u:adj[centroid]){
		if (vis[u.F]) continue;
		if (w[u.S] && dis==h){
			vis[u.F]=1;
			//cout<<u.F<<' ';
		}
		if (!w[u.S] && dis<h){
			vis[u.F]=1;
			//cout<<u.F<<' ';
		}
	}
	//cout<<endl<<endl;
	return centroid_decomposition(centroid);
}
void getdep(int x,int par){
	mxdep[x]=dep[x];
	for (auto u:adj[x]){
		if (u.F==par) continue;
		p[u.F]=u.S;
		dep[u.F]=dep[x]+1;
		getdep(u.F,x);
		mxdep[x]=max(mxdep[x],mxdep[u.F]);
	}return;
}
void dfss(int x,int par){
	for (auto u:adj[x]){
		if (u.F==par || mxdep[u.F]<dis || dep[u.F]>dis) continue;
		w[u.S]=1;
		dfss(u.F,x);
	}return;
}
void find_pair(int N, std::vector<int> U, std::vector<int> V, int A, int B){
	n=N;
	m=U.size();
	for (int i=0;i<m;i++){
		adj[U[i]].pb({V[i],i});
		adj[V[i]].pb({U[i],i});
	}
	w.resize(m);
	dis=ask(w);
	int s=centroid_decomposition(0),h;
	//cout<<s<<endl;
	for (auto u:adj[s]) if (!vis[u.F]) h=u.F;
	if (dis==A){
		answer(s,h);
		return;
	}
	for (int i=0;i<n;i++) vis[i]=0;
	for (int i=0;i<m;i++) w[i]=0;
	getdep(s,-1);
	dis/=A;
	dfss(s,-1);
	ll f=ask(w);
	//cout<<s<<' '<<h<<endl;
	if (f!=dis*(ll)B) swap(s,h),dep[s]=0,getdep(s,-1); 
	vector<int> v;
	for (int i=0;i<n;i++){
		if (dep[i]==dis) v.pb(i);
	}
	while (v.size()>1){
		int mid=v.size()/2;
		for (int i=0;i<m;i++) w[i]=0;
		for (int i=0;i<mid;i++) w[p[v[i]]]=1;
		f=ask(w);
		if (f>dis*(ll)A){
			while (v.size()>mid) v.ppb();
		}
		else{
			reverse(v.begin(),v.end());
			for (int i=0;i<mid;i++) v.ppb();
		}
	}
	//cout<<s<<endl;
	answer(s,v[0]);
	return;
}
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...