Submission #162936

#TimeUsernameProblemLanguageResultExecution timeMemory
162936MinnakhmetovHighway Tolls (IOI18_highway)C++14
51 / 100
309 ms13184 KiB
#include "highway.h"
#include <bits/stdc++.h>

using namespace std;

#define ll long long
#define all(aaa) aaa.begin(), aaa.end()

struct E {
	int to, i;
};

const int N = 2e5 + 5;
vector<E> g[N];
int anc[N], d[N];

void find_pair(int n, vector<int> u, vector<int> v, int a, int b) {
	int m = u.size();

	for (int i = 0; i < m; i++) {
		g[u[i]].push_back({v[i], i});
		g[v[i]].push_back({u[i], i});
	}

	ll dist = ask(vector<int>(m, 0)) / a;

	int l = -1, r = m - 1;
	while (r - l > 1) {
		int p = (l + r) >> 1;
		vector<int> w(m, 0);
		fill(w.begin(), w.begin() + p + 1, 1);
		if (ask(w) != dist * a)
			r = p;
		else
			l = p;
	}

	int root = u[r];

	// cout << root << "\n";

	queue<int> q;
	fill(d, d + n, -1);
	d[root] = 0;
	q.push(root);

	vector<int> tree_edges;

	while (!q.empty()) {
		int node = q.front();
		q.pop();

		for (E e : g[node]) {
			if (d[e.to] == -1) {
				d[e.to] = d[node] + 1;
				anc[e.to] = e.i;
				tree_edges.push_back(e.i);
				q.push(e.to);
			}
		}
	}

	for (int i = 0; i < m; i++) {
		if (d[u[i]] > d[v[i]])
			swap(u[i], v[i]);
	}

	sort(all(tree_edges), [&](int x, int y) {
		return d[v[x]] > d[v[y]];
	});

	l = -1, r = int(tree_edges.size()) - 1;

	while (r - l > 1) {
		int p = (l + r) >> 1;
		vector<int> w(m, 1);

		for (int i = p + 1; i < tree_edges.size(); i++) {
			w[tree_edges[i]] = 0;
		}

		if (ask(w) != dist * a)
			r = p;
		else
			l = p;
	}

	int s = v[tree_edges[r]],
		x = s;

	vector<int> half;

	while (x != root) {
		half.push_back(anc[x]);
		x = u[anc[x]];
	}

	if (half.size() == dist) {
		answer(root, s);
	}
	else {
		l = r, r = int(tree_edges.size()) - 1;

		while (r - l > 1) {
			int p = (l + r) >> 1;
			vector<int> w(m, 1);

			for (int i = p + 1; i < tree_edges.size(); i++) {
				w[tree_edges[i]] = 0;
			}

			ll need = dist * a;

			for (int i : half) {
				if (w[i])
					need += b - a;
			}

			if (ask(w) != need)
				r = p;
			else
				l = p;
		}

		int t = v[tree_edges[r]];

		answer(s, t);
	}

}

Compilation message (stderr)

highway.cpp: In function 'void find_pair(int, std::vector<int>, std::vector<int>, int, int)':
highway.cpp:78:25: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for (int i = p + 1; i < tree_edges.size(); i++) {
                       ~~^~~~~~~~~~~~~~~~~~~
highway.cpp:98:18: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  if (half.size() == dist) {
      ~~~~~~~~~~~~^~~~~~~
highway.cpp:108:26: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
    for (int i = p + 1; i < tree_edges.size(); i++) {
                        ~~^~~~~~~~~~~~~~~~~~~
#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...