제출 #1336525

#제출 시각아이디문제언어결과실행 시간메모리
1336525gelastropod통행료 (IOI18_highway)C++20
90 / 100
100 ms12940 KiB
#include "highway.h"

#include <bits/stdc++.h>
#include <random>
using namespace std;

int cnt = 0;
vector<vector<pair<int, int>>> adjlist;
vector<int> ei, pre, visited, spec, perm;

void find_pair(int N, std::vector<int> U, std::vector<int> V, int A, int B) {
	for (int i = 0; i < 4; i++) ask(vector<int>(U.size(), 0));
	for (int i = 0; i < N; i++) perm.push_back(i);
	mt19937 mt(1434);
	shuffle(perm.begin(), perm.end(), mt);
	vector<int> rperm(N, 0);
	for (int i = 0; i < N; i++) rperm[perm[i]] = i;
	for (int i = 0; i < U.size(); i++) U[i] = perm[U[i]], V[i] = perm[V[i]];
	adjlist.resize(N, vector<pair<int, int>>());
	ei.resize(N, -1);
	pre.resize(N, 0);
	spec.resize(N, 0);
	visited.resize(N, 0);
	int M = U.size();
	for (int i = 0; i < M; i++) {
		adjlist[U[i]].push_back({ V[i], i });
		adjlist[V[i]].push_back({ U[i], i });
	}
	vector<int> w(M, 0);
	int pl = ask(w) / A;
	int low = 0, high = M - 1, ans = -1;
	while (low <= high) {
		int x = (low + high) / 2;
		w = vector<int>(M, 0);
		for (int i = 0; i <= x; i++) w[i] = 1;
		int res = ask(w);
		if (res != A * pl) ans = x, high = x - 1;
		else low = x + 1;
	}
	for (int i = 0; i < adjlist[U[ans]].size(); i++) if (adjlist[U[ans]][i].first == V[ans]) swap(adjlist[U[ans]][0], adjlist[U[ans]][i]);
	queue<pair<int, int>> bfs;
	bfs.push({ U[ans], 0 });
	bfs.push({ V[ans], 1 });
	visited[U[ans]] = visited[V[ans]] = 1;
	ei[V[ans]] = ans;
	while (bfs.size()) {
		auto i = bfs.front(); bfs.pop();
		spec[i.first] = i.second;
		for (auto j : adjlist[i.first]) {
			if (visited[j.first]) continue;
			visited[j.first] = 1;
			pre[j.first] = pre[i.first] + 1;
			ei[j.first] = j.second;
			bfs.push({ j.first, i.second });
		}
	}
	vector<int> special, notspecial;
	for (int i = 0; i < N; i++) {
		if (spec[i]) special.push_back(i);
		else notspecial.push_back(i);
	}
	sort(special.begin(), special.end(), [](auto a, auto b) {return pre[a] < pre[b]; });
	sort(notspecial.begin(), notspecial.end(), [](auto a, auto b) {return pre[a] < pre[b]; });
	low = 1, high = special.size() - 1;
	int ans1 = 0, ans2 = 0;
	w = vector<int>(M, 1);
	for (int i = 0; i < N; i++) if (i != U[ans]) w[ei[i]] = 0;
	while (low <= high) {
		int x = (low + high) / 2;
		vector<int> _w = w;
		for (int i = x; i < special.size(); i++) _w[ei[special[i]]] = 1;
		int res = ask(_w);
		if (res != A * pl) ans1 = x, low = x + 1;
		else high = x - 1;
	}
	int firstn = special[ans1];
	int gd = pl - 1 - pre[firstn];
	vector<int> eee;
	for (int i : notspecial) if (pre[i] == gd) eee.push_back(i);
	notspecial = eee;
	low = 1, high = notspecial.size() - 1;
	while (low <= high) {
		int x = (low + high) / 2;
		vector<int> _w = w;
		for (int i = x; i < notspecial.size(); i++) _w[ei[notspecial[i]]] = 1;
		int res = ask(_w);
		if (res != A * pl) ans2 = x, low = x + 1;
		else high = x - 1;
	}
	answer(rperm[special[ans1]], rperm[notspecial[ans2]]);
}
#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...