This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include "highway.h"
#include <bits/stdc++.h>
using namespace std;
int N, M, U[1 << 18], V[1 << 18], dist[1 << 18], par[1 << 18], paredge[1 << 18];
vector<pair<int, int>> G[1 << 18]; bool anti[1 << 18];
vector<int> GG[1<<18]; int depth[1<<18], BB[1<<18];
map<pair<int, int>, int>MM;
void dfs(int pos, int dep) {
depth[pos] = dep;
for (int i = 0; i < GG[pos].size(); i++) {
if(depth[GG[pos][i]] != -1) continue;
par[GG[pos][i]] = pos;
BB[GG[pos][i]] = MM[make_pair(GG[pos][i], pos)];
dfs(GG[pos][i], dep + 1);
}
}
void find_pair(int NN, vector<int> UU, vector<int> VV, int A, int B) {
if (NN - 1 == (int)UU.size()) {
N = NN;
for (int i = 0; i < UU.size(); i++) {
GG[UU[i]].push_back(VV[i]);
GG[VV[i]].push_back(UU[i]);
MM[make_pair(UU[i], VV[i])] = i; MM[make_pair(VV[i], UU[i])] = i;
}
for (int i = 0; i < N; i++) depth[i] = -1;
dfs(0, 0);
vector<int> W(N - 1, 0);
for (int i = 0; i < N - 1; i++) W[i] = 0; long long c1 = ask(W);
for (int i = 0; i < N - 1; i++) W[i] = 1; long long c2 = ask(W);
vector<pair<int, int>> T;
for (int i = 1; i < N; i++) T.push_back(make_pair(depth[i], i));
sort(T.begin(), T.end());
// Part 1. Find the lowest
int L1 = 0, R1 = N - 1, M1, ret1 = 0;
for (int i = 0; i < 19; i++) {
M1 = (L1 + R1) / 2;
for (int j = 0; j < T.size(); j++) { if (j < M1) W[BB[T[j].second]] = 0; else W[BB[T[j].second]] = 1; }
long long c3 = ask(W);
if (c1 == c3) { R1 = M1; }
else { L1 = M1; ret1 = max(ret1, M1); }
}
int cx = T[ret1].second;
while (true) {
anti[cx] = true; if (cx == 0) break;
cx = par[cx];
}
// Part 2. Find the highest
int L2 = 0, R2 = N - 1, M2, ret2 = N - 2;
for (int i = 0; i < 19; i++) {
M2 = (L2 + R2) / 2;
for (int j = 0; j < T.size(); j++) { if (j <= M2) W[BB[T[j].second]] = 1; else W[BB[T[j].second]] = 0; }
long long c3 = ask(W);
if (c1 == c3) { L2 = M2; }
else { R2 = M2; ret2 = min(ret2, M2); }
}
// Part 3. Find the second
long long P1 = T[ret1].first, P2 = T[ret2].first - 1, Leng = (c2 - c1) / (1LL * B - 1LL * A);
long long P3 = P2 + (Leng - (P1 - P2));
if (P3 == P2) {
answer(par[T[ret2].second], T[ret1].second);
return;
}
vector<int>I;
for (int i = 0; i < N; i++) {
if (depth[i] == P3 && anti[i] == false) { I.push_back(i); }
}
int L3 = 0, R3 = I.size(), M3, ret3 = I.size() - 1;
for (int i = 0; i < 19; i++) {
M3 = (L3 + R3) / 2;
for (int j = 0; j < N; j++) W[j] = 0;
for (int j = 0; j <= M3; j++) W[BB[I[j]]] = 1;
long long c3 = ask(W);
if (c1 == c3) { L3 = M3; }
else { R3 = M3; ret3 = min(ret3, M3); }
}
answer(I[ret3], T[ret1].second);
return;
}
// ----------------------------- Step 0: Input ---------------------------
N = NN; M = UU.size();
for (int i = 0; i < M; i++) { U[i] = UU[i]; V[i] = VV[i]; }
// -------------------------- Step 1: Get All-A --------------------------
vector<int> W(M, 0);
long long BASE = ask(W), DIST = BASE / A;
// ---------------------- Step 2: The Minimum Vertex ---------------------
int c1 = 0;
for (int i = 16; i >= 0; i--) {
for (int j = 0; j < M; j++) {
if (min(U[j], V[j]) >= c1 + (1 << i)) W[j] = 0;
else W[j] = 1;
}
long long p1 = ask(W);
if (p1 == BASE) { c1 += (1 << i); }
}
// -------------------------- Step 3: Make Tree --------------------------
for (int i = 0; i < M; i++) {
if (min(U[i], V[i]) < c1) continue;
G[U[i]].push_back(make_pair(V[i], i));
G[V[i]].push_back(make_pair(U[i], i));
}
for (int i = 0; i < N; i++) dist[i] = (1 << 30);
queue<int> que; que.push(c1); dist[c1] = 0;
while (!que.empty()) {
int pos1 = que.front(); que.pop();
for (int i = 0; i < G[pos1].size(); i++) {
int to = G[pos1][i].first;
if (dist[to] > dist[pos1] + 1) {
dist[to] = dist[pos1] + 1;
que.push(to);
}
}
}
for (int i = c1 + 1; i < N; i++) {
for (int j = 0; j < G[i].size(); j++) {
int to = G[i][j].first;
if (dist[i] > dist[to]) { par[i] = to; paredge[i] = G[i][j].second; break; }
}
}
// ---------------------------- 4. Find T --------------------------------
vector<pair<int, int>> V;
for (int i = c1 + 1; i < N; i++) {
if (dist[i] == (1 << 30)) continue;
V.push_back(make_pair(dist[i], i));
}
sort(V.begin(), V.end());
//for (int i = 0; i < V.size(); i++) cout << "V[" << i << "] = " << V[i].second << endl;
int c2 = 0;
for (int i = 16; i >= 0; i--) {
for (int j = 0; j < W.size(); j++) W[j] = 1;
for (int j = 0; j < c2 + (1 << i); j++) {
if (j >= V.size()) break;
W[paredge[V[j].second]] = 0;
}
long long p2 = ask(W);
if (p2 != BASE) c2 += (1 << i);
}
// --------------------- 5. Find the candidate of S ----------------------
long long T = V[c2].second, cand_dst = DIST - dist[T];
if (cand_dst == 0) {
answer(T, c1);
return;
}
int cx = T; anti[cx] = true;
while (true) {
cx = par[cx];
anti[cx] = true;
if (cx == c1) break;
}
vector<int> V2;
for (int i = c1 + 1; i < N; i++) {
if (dist[i] == cand_dst && anti[i] == false) V2.push_back(i);
}
// ----------------------------- 6. Find S --------------------------------
int c3 = 0;
for (int i = 16; i >= 0; i--) {
for (int j = 0; j < W.size(); j++) W[j] = 1;
for (int j = c1 + 1; j < W.size(); j++) W[paredge[j]] = 0;
for (int j = 0; j < c3 + (1 << i); j++) {
if (j >= V2.size()) break;
W[paredge[V2[j]]] = 1;
}
long long p3 = ask(W);
if (p3 == BASE) c3 += (1 << i);
}
long long S = V2[c3];
answer(S, T);
return;
}
Compilation message (stderr)
highway.cpp: In function 'void dfs(int, int)':
highway.cpp:13:20: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
for (int i = 0; i < GG[pos].size(); i++) {
~~^~~~~~~~~~~~~~~~
highway.cpp: In function 'void find_pair(int, std::vector<int>, std::vector<int>, int, int)':
highway.cpp:24:21: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
for (int i = 0; i < UU.size(); i++) {
~~^~~~~~~~~~~
highway.cpp:33:3: warning: this 'for' clause does not guard... [-Wmisleading-indentation]
for (int i = 0; i < N - 1; i++) W[i] = 0; long long c1 = ask(W);
^~~
highway.cpp:33:45: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'for'
for (int i = 0; i < N - 1; i++) W[i] = 0; long long c1 = ask(W);
^~~~
highway.cpp:34:3: warning: this 'for' clause does not guard... [-Wmisleading-indentation]
for (int i = 0; i < N - 1; i++) W[i] = 1; long long c2 = ask(W);
^~~
highway.cpp:34:45: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'for'
for (int i = 0; i < N - 1; i++) W[i] = 1; long long c2 = ask(W);
^~~~
highway.cpp:44:22: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
for (int j = 0; j < T.size(); j++) { if (j < M1) W[BB[T[j].second]] = 0; else W[BB[T[j].second]] = 1; }
~~^~~~~~~~~~
highway.cpp:60:22: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
for (int j = 0; j < T.size(); j++) { if (j <= M2) W[BB[T[j].second]] = 1; else W[BB[T[j].second]] = 0; }
~~^~~~~~~~~~
highway.cpp:126:21: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
for (int i = 0; i < G[pos1].size(); i++) {
~~^~~~~~~~~~~~~~~~
highway.cpp:136:21: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
for (int j = 0; j < G[i].size(); j++) {
~~^~~~~~~~~~~~~
highway.cpp:154:21: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
for (int j = 0; j < W.size(); j++) W[j] = 1;
~~^~~~~~~~~~
highway.cpp:156:10: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
if (j >= V.size()) break;
~~^~~~~~~~~~~
highway.cpp:185:21: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
for (int j = 0; j < W.size(); j++) W[j] = 1;
~~^~~~~~~~~~
highway.cpp:186:26: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
for (int j = c1 + 1; j < W.size(); j++) W[paredge[j]] = 0;
~~^~~~~~~~~~
highway.cpp:189:10: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
if (j >= V2.size()) break;
~~^~~~~~~~~~~~
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |