#include "migrations.h"
#include <bits/stdc++.h>
#ifdef LOCAL
#include "Debug.h"
#else
#define debug(...) 42
#endif
using namespace std;
const int N = 1e4;
const int Z = 4;
const int POW[] = {1, 4, 16, 64, 256};
const int A = N - 1;
const int B = N - 2;
const int C = N - 3;
const int D = N - 4;
// phase 0: 4 messages in 48 pos (50937665) -> need 1225
// phase 1: 3 messages in 6 pos (1545) -> need 21
// phase 2: 2 messages in 2 pos (25) -> 2 unknown
// phase 3: 2 messages to for final 4 pos
const vector<int> POS = {48, 6, 2, 2};
const int FROM = N - accumulate(begin(POS), end(POS), 0);
const vector<int> MSG = {4, 3, 2, 2};
vector<int> a[N];
int n, u[N], v[N], maxDist, dist[N];
vector<vector<int>> seqs;
vector<int> seq, mess;
void gen(int i, int pos, int msg, int last)
{
seqs.push_back(seq);
if (i == msg)
return;
for (int x = last + 1; x < pos; x++)
{
seq.push_back(x);
gen(i + 1, pos, msg, x);
seq.pop_back();
}
}
void dfs(int x)
{
for (int y : a[x])
if (dist[y] < 0)
{
dist[y] = dist[x] + 1;
dfs(y);
}
}
vector<int> toMessage(int value, int len)
{
vector<int> mes(len);
for (auto seq : seqs)
{
int sz = size(seq);
if (value >= POW[sz]) value -= POW[sz];
else
{
for (int id : seq)
{
mes[id] = value % Z + 1;
value /= Z;
}
return mes;
}
}
assert(0);
return {};
}
int fromMessage(vector<int> ids, vector<int> vals)
{
int value = 0;
for (auto seq : seqs)
if (seq != ids) value += POW[size(seq)];
else
{
for (int i = 0; i < size(seq); i++)
value += (vals[i] - 1) * POW[i];
return value;
}
assert(0);
return 0;
}
int getPhase0Value(int i)
{
if (u[i] > v[i])
swap(u[i], v[i]);
return (n - 1 + n - u[i]) * u[i] / 2 + (v[i] - u[i] - 1);
}
pair<int, int> fromPhase0Value(int value)
{
int u = 0, v = 0;
while (value >= n - 1 - u)
{
value -= n - 1 - u;
u++;
}
v = u + 1 + value;
return {u, v};
}
int match(int x, int y, int xx, int yy)
{
return (x == xx && y == yy) || (x == yy && y == xx);
}
int getPhase12Value(int from, int to) // [from, to]
{
int value = 0;
for (int j = from; j < to; j++)
for (int k = j + 1; k <= to; k++)
{
if (match(u[to], v[to], j, k))
return value; // x, y
value++;
}
for (int j = from; j <= to; j++)
{
if (u[to] == j)
return value; // x, _
value++;
if (v[to] == j)
return value; // _, x
value++;
}
return value; // _, _
}
pair<int, int> fromPhase12Value(int value, int from, int to, int u, int v) // [from, to]
{
for (int j = from; j < to; j++)
for (int k = j + 1; k <= to; k++)
{
if (value == 0)
return {j, k};
value--;
}
for (int j = from; j <= to; j++)
{
if (value == 0)
return {j, v};
value--;
if (value == 0)
return {u, j};
value--;
}
return {u, v};
}
int send_message(int _, int i, int Pi) {
n = N;
if (i == 1)
u[0] = v[0] = maxDist = 0;
a[i].push_back(Pi);
a[Pi].push_back(i);
memset(dist, -1, sizeof dist);
dist[i] = 0;
dfs(i);
u[i] = u[i - 1];
v[i] = v[i - 1];
if (dist[v[i]] > maxDist)
{
u[i] = i;
maxDist = dist[v[i]];
}
else if (dist[u[i]] > maxDist)
{
v[i] = i;
maxDist = dist[u[i]];
}
if (i < FROM)
return 0;
if (i == FROM + POS[0] && FROM + 1 <= v[i] && v[i] < u[i])
swap(u[i], v[i]);
if (i == FROM + POS[0] + POS[1] - 1 && FROM + POS[0] + 1 <= v[i] && v[i] < u[i])
swap(u[i], v[i]);
// --------------------- phase 0 ---------------------
if (i < FROM + POS[0])
{
if (i == FROM)
{
seqs.clear();
seq.clear();
gen(0, POS[0], MSG[0], -1);
mess = toMessage(getPhase0Value(i), POS[0]);
}
return mess[i - FROM];
}
// --------------------- phase 1 ---------------------
if (i < FROM + POS[0] + POS[1])
{
if (i == FROM + POS[0])
{
seqs.clear();
seq.clear();
gen(0, POS[1], MSG[1], -1);
mess = toMessage(getPhase12Value(FROM + 1, i), POS[1]);
}
return mess[i - FROM - POS[0]];
}
// --------------------- phase 2 ---------------------
if (i < FROM + POS[0] + POS[1] + POS[2])
{
if (i == FROM + POS[0] + POS[1])
{
int value = getPhase12Value(FROM + POS[0] + 1, i - 1);
debug("phase 2", value);
assert(value < 21);
mess = {value % 5, value / 5};
}
return mess[i - FROM - POS[0] - POS[1]];
}
// --------------------- phase 3 ---------------------
// n - 2
if (i == n - 2)
{
mess = {-1};
if (match(u[i], v[i], B, C)) mess[0] = 0; // bc
if (u[i] == B && v[i] < D) mess[0] = 0; // b_
if (match(u[i], v[i], C, D)) mess[0] = 1; // cd
if (u[i] == C && v[i] < D) mess[0] = 1; // c_
if (match(u[i], v[i], B, D)) mess[0] = 2; // bd
if (u[i] < D && v[i] == B) mess[0] = 2; // _b
if (u[i] == D && v[i] < D) mess[0] = 3; // d_
if (u[i] < D && v[i] == D) mess[0] = 3; // _d
if (u[i] < D && v[i] == C) mess[0] = 4; // _c
if (u[i] < D && v[i] < D) mess[0] = 4; // __
return mess[0];
}
// n - 1
if (mess[0] == 0)
{
if (match(u[i], v[i], A, B)) return 0; // ab
if (match(u[i], v[i], A, C)) return 1; // ac
if (match(u[i], v[i], B, C)) return 2; // bc
if (u[i] == A && v[i] < D) return 3; // a_
if (u[i] == B && v[i] < D) return 4; // b_
assert(0 && "fail s[n - 2] = 0");
}
if (mess[0] == 1)
{
if (match(u[i], v[i], A, C)) return 0; // ac
if (match(u[i], v[i], A, D)) return 1; // ad
if (match(u[i], v[i], C, D)) return 2; // cd
if (u[i] == A && v[i] < D) return 3; // a_
if (u[i] == C && v[i] < D) return 4; // c_
assert(0 && "fail s[n - 2] = 1");
}
if (mess[0] == 2)
{
if (match(u[i], v[i], A, B)) return 0; // ab
if (match(u[i], v[i], A, D)) return 1; // ad
if (match(u[i], v[i], B, D)) return 2; // bd
if (u[i] < D && v[i] == A) return 3; // _a
if (u[i] < D && v[i] == B) return 4; // _b
assert(0 && "failed s[n - 2] = 2");
}
if (mess[0] == 3)
{
if (match(u[i], v[i], A, D)) return 0; // ad
if (u[i] == A && v[i] < D) return 1; // a_
if (u[i] < D && v[i] == A) return 2; // _a
if (u[i] == D && v[i] < D) return 3; // d_
if (u[i] < D && v[i] == D) return 4; // _d
assert(0 && "failed s[n - 2] = 3");
}
if (mess[0] == 4)
{
if (match(u[i], v[i], A, C)) return 0; // ac
if (u[i] == A && v[i] < D) return 1; // a_
if (u[i] < D && v[i] == A) return 2; // _a
if (u[i] < D && v[i] == C) return 3; // _c
if (u[i] < D && v[i] < D) return 4; // __
assert(0 && "failed s[n - 2] = 4");
}
assert(0 && "invalid s[n - 2]");
return 0;
}
pair<vector<int>, vector<int>> getMessage(vector<int> &s, int from, int to) // [from, to)
{
vector<int> ids, vals;
for (int i = from; i < to; i++)
if (s[i])
{
ids.push_back(i - from);
vals.push_back(s[i]);
}
return {ids, vals};
}
pair<int, int> longest_path(vector<int> s)
{
n = size(s);
// --------------------- phase 0 ---------------------
seqs.clear();
seq.clear();
gen(0, POS[0], MSG[0], -1);
auto [ids0, vals0] = getMessage(s, FROM, FROM + POS[0]);
int value0 = fromMessage(ids0, vals0);
auto [u, v] = fromPhase0Value(value0);
debug("phase 0", value0, u, v);
// --------------------- phase 1 ---------------------
seqs.clear();
seq.clear();
gen(0, POS[1], MSG[1], -1);
auto [ids1, vals1] = getMessage(s, FROM + POS[0], FROM + POS[0] + POS[1]);
int value1 = fromMessage(ids1, vals1);
tie(u, v) = fromPhase12Value(value1, FROM + 1, FROM + POS[0], u, v);
debug("phase 1", value1, u, v);
// --------------------- phase 2 ---------------------
int value2 = s[FROM + POS[0] + POS[1]] + s[FROM + POS[0] + POS[1] + 1] * 5;
tie(u, v) = fromPhase12Value(value2, FROM + POS[0] + 1, FROM + POS[0] + POS[1] - 1, u, v);
debug("phase 2", value2, u, v);
// --------------------- phase 3 ---------------------
if (s[n - 2] == 0)
{
if (s[n - 1] == 0) return {A, B};
if (s[n - 1] == 1) return {A, C};
if (s[n - 1] == 2) return {B, C};
if (s[n - 1] == 3) return {A, v};
if (s[n - 1] == 4) return {B, v};
}
if (s[n - 2] == 1)
{
if (s[n - 1] == 0) return {A, C};
if (s[n - 1] == 1) return {A, D};
if (s[n - 1] == 2) return {C, D};
if (s[n - 1] == 3) return {A, v};
if (s[n - 1] == 4) return {C, v};
}
if (s[n - 2] == 2)
{
if (s[n - 1] == 0) return {A, B};
if (s[n - 1] == 1) return {A, D};
if (s[n - 1] == 2) return {B, D};
if (s[n - 1] == 3) return {u, A};
if (s[n - 1] == 4) return {u, B};
}
if (s[n - 2] == 3)
{
if (s[n - 1] == 0) return {A, D};
if (s[n - 1] == 1) return {A, v};
if (s[n - 1] == 2) return {u, A};
if (s[n - 1] == 3) return {D, v};
if (s[n - 1] == 4) return {u, D};
}
if (s[n - 2] == 4)
{
if (s[n - 1] == 0) return {A, C};
if (s[n - 1] == 1) return {A, v};
if (s[n - 1] == 2) return {u, A};
if (s[n - 1] == 3) return {u, C};
if (s[n - 1] == 4) return {u, v};
}
assert(0 && "invalid s[n - 2]");
return {u, v};
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |