Submission #1274738

#TimeUsernameProblemLanguageResultExecution timeMemory
1274738nicolo_010Highway Tolls (IOI18_highway)C++20
100 / 100
114 ms11604 KiB
#include <bits/stdc++.h>
#include "highway.h"
using namespace std;
using ll = long long;
using pii = pair<int, int>;

vector<vector<pii>> adj;
vector<int> endp;
vector<int> edge;
int t;
vector<int> query;
ll w;

int first(int M) {
	int l = 0, r = M-1;
	int ans = 0;
	while (l <= r) {
		int m = (l+r)/2;
		for (int i=0; i<M; i++) {
			query[i] = (i <= m);
		}
		ll w2 = ask(query);
		if (w2 != w) {
			r=m-1;
		}
		else {
			l = m+1;
			ans = m+1;
		}
	}
	return ans;
}

int last(int M) {
	int l=0, r = t-1;
	int ans=-1;
	while (l <= r) {
		int m = (l+r+1)/2;
		for (int i=0; i<M; i++) {
			query[i] = (edge[i] >= m);
		}
		ll w2 = ask(query);
		if (w2 != w) {
			l = m+1;
			ans = m;
		}
		else {
			r = m-1;
		}
	}
	return ans;
}

void find_pair(int N, vector<int> U, vector<int> V, int A, int B) {
	int m = U.size();
	query.assign(m, 0);
	w = ask(query);
	adj.resize(N);
	for (int i=0; i<m; i++) {
		int a = U[i];
		int b = V[i];
		adj[a].push_back({i, b});
		adj[b].push_back({i, a});
	}
	edge.resize(m);
	endp.resize(m);
	vector<int> ans(2);
	int e = first(m);
	vector<int> disv[2];
	vector<int> v = {U[e], V[e]};
	for (int i=0; i<2; i++) {
		queue<int> q;
		vector<int> dis(N, -1);
		dis[v[i]] = 0;
		q.push(v[i]);
		while (!q.empty()) {
			int u = q.front();
			q.pop();
			for (auto x : adj[u]) {
				if (dis[x.second] == -1) {
					dis[x.second] = dis[u]+1;
					q.push(x.second);
				}
			}
		}
		disv[i] = dis;
	}
	for (int i=0; i<2; i++) {
		edge.assign(m, -1);
		t = 0;
		queue<int> q;
		vector<int> dis(N, -1);
		dis[v[i]] = 0;
		q.push(v[i]);
		while (!q.empty()) {
			int u = q.front();
			q.pop();
			for (auto x : adj[u]) {
				if (disv[i][x.second] < disv[1-i][x.second]) {
					if (dis[x.second] == -1) {
						dis[x.second] = dis[u]+1;
						endp[t] = x.second;
						edge[x.first] = t++;
						q.push(x.second);
					}
					else if (dis[x.second] == dis[u]+1) {
						edge[x.first] = N;
					}
				}
				else if (x.first != e) {
					edge[x.first] = N;
				}
			}
		}
		int le = last(m);
		ans[i] = (le == -1 ? v[i] : endp[le]);
	}
	answer(ans[0], ans[1]);
}
#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...