#include "migrations.h"
#include <bits/stdc++.h>
using namespace std;
const int N = 10000;
int x = 0, y = 1;
bool done_x = 0, done_y = 0;
int par[16][N + 5];
int depth[N + 5];
// calculate distance between two nodes
int dist(int x, int y) {
if (depth[x] < depth[y]) {
swap(x, y);
}
int res = 0;
for (int i = 15; i >= 0; --i) {
if (par[i][x] != -1 && depth[par[i][x]] >= depth[y]) {
x = par[i][x];
res += 1 << i;
}
}
if (x == y) {
return res;
}
for (int i = 15; i >= 0; --i) {
if (par[i][x] != par[i][y]) {
x = par[i][x];
y = par[i][y];
res += 1 << (i + 1);
}
}
return res + 2;
}
int send_message(int N, int nd, int pr) {
// special init case
if (nd == 1) {
memset(par, -1, sizeof(par));
par[0][1] = 0;
depth[1] = 1;
return 0;
}
// calc binlift and depth
depth[nd] = depth[pr] + 1;
par[0][nd] = pr;
for (int i = 1; i < 16; ++i) {
if (par[i - 1][nd] != -1) {
par[i][nd] = par[i - 1][par[i - 1][nd]];
}
}
// check dist(x, nd), dist(y, nd), see if x or y changed
bool cx = 0, cy = 0;
if (dist(x, nd) > dist(x, y)) {
cy = 1;
y = nd;
} else if (dist(y, nd) > dist(x, y)) {
cx = 1;
x = nd;
}
if (nd >= N - 20 && nd < N - 12) {
// communicate x phase
if (done_x) {
return cx;
} else if (cx) {
done_x = 1;
return 0;
} else {
int num = nd - (N - 20); // the num-th message we send for x, starting from 0
int cur = (x >> (2 * num)) & 3;
return cur + 1;
}
} else if (nd >= N - 12) {
// communicate y phase
if (nd < N - 4) {
if (done_y) {
return cy;
} else if (cy) {
done_y = 1;
return 0;
} else {
int num = nd - (N - 12); // the num-th message we send for x, starting from 0
int cur = (y >> (2 * num)) & 3;
return cur + 1;
}
} else {
if (nd == N - 4) {
// get x
if (x == nd) {
return 0; // reset to nd
} else if (x < N - 12) {
return 1; // no reset
} else if (x >= N - 12) {
return ((x - (N - 12)) / 3) + 2;
}
} else if (nd == N - 3) {
// get x
if (x == nd) {
return 0; // reset to nd
} else if (x == nd - 1 || x < N - 12) {
return 1; // no reset
} else {
return ((x - (N - 12)) % 3) + 2;
}
} else if (nd == N - 2) {
// get y
if (y < N - 4) {
return 0;
} else {
return N - 1 - y; // N - 2 -> 1, N - 3 -> 2, N - 4 -> 3
}
} else if (nd == N - 1) {
// get y cur, x last two
// 1. no reset
// 2. x reset n - 2, y reset n - 1
// 3. x reset n - 2, y no reset
// 4. x reset n - 1
if (y < N - 1 && x < N - 2) {
return 1;
} else if (x == N - 2 && y == N - 1) {
return 2;
} else if (x == N - 2) {
return 3;
} else if (x == N - 1) {
return 4;
} else {
assert(false);
}
}
}
}
// default
return 0;
}
std::pair<int, int> longest_path(std::vector<int> S) {
int val_x = 0, val_y = 0, shift = 0;
bool done_x = 0, done_y = 0;
// communicate x phase
for (int i = N - 20; i < N - 12; ++i) {
if (done_x) {
val_x = S[i] == 1 ? i : val_x;
} else {
if (S[i] == 0) {
val_x = i, done_x = i;
} else {
val_x += (S[i] - 1) << shift;
shift += 2;
}
}
}
shift = 0;
// communicate y phase
for (int i = N - 12; i < N - 4; ++i) {
if (done_y) {
val_y = S[i] == 1 ? i : val_y;
} else {
if (S[i] == 0) {
val_y = i, done_y = i;
} else {
val_y += (S[i] - 1) << shift;
shift += 2;
}
}
}
// N - 4
{
int idx = N - 4;
if (S[idx] == 0) {
val_x = idx;
} else if (S[idx] != 1) {
val_x = N - 12 + (S[idx] - 2) * 3;
}
}
// N - 3
{
int idx = N - 3;
if (S[idx] == 0) {
val_x = idx;
} else if (S[idx] != 1) {
val_x += S[idx] - 2;
}
}
// N - 2
{
int idx = N - 2;
if (S[idx] > 0) {
val_y = N - 1 - S[idx];
}
}
// N - 1
{
int idx = N - 1;
if (S[idx] == 2) {
val_x = N - 2, val_y = N - 1;
} else if (S[idx] == 3) {
val_x = N - 2;
} else if (S[idx] == 4) {
val_x = N - 1;
}
}
return {val_x, val_y};
}
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |