This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
// PinkRabbit
#include "parks.h"
#include <cstdio>
#include <algorithm>
#include <vector>
#include <map>
#include <ctime>
#include <random>
#include <chrono>
std::mt19937_64 rng(std::chrono::steady_clock::now().time_since_epoch().count());
template<typename T>
inline T range(T l, T r) {
return std::uniform_int_distribution<T>(l, r)(rng);
}
template<typename T>
inline void vec2arr(std::vector<T> v, T *arr, T bias = 0) {
int n = (int)v.size();
for (int i = 1; i <= n; ++i)
arr[i] = v[i - 1] + bias;
}
template<typename T>
inline std::vector<T> arr2vec(T *arr, int n, T bias = 0) {
std::vector<T> v(n);
for (int i = 1; i <= n; ++i)
v[i - 1] = arr[i] + bias;
return v;
}
typedef std::vector<int> VI;
const int MN = 800005;
const int MV = 400005;
const int dx[4] = {0, 1, 0, -1};
const int dy[4] = {1, 0, -1, 0};
int N;
int x[MN], y[MN];
int ndir[MN][4], edir[MN][4];
std::map<int, int> mp[MV];
int eu[MN * 2], ev[MN * 2], M;
int per[MN * 2], iper[MN * 2];
int AnsU[MN], AnsV[MN], AnsA[MN], AnsB[MN];
int pa[MN];
int fp(int u) {
return pa[u] ? pa[u] = fp(pa[u]) : u;
}
inline bool GenTree() {
int tot = 0;
std::shuffle(per + 1, per + M + 1, rng);
for (int i = 1; i <= M; ++i)
iper[i] = 0;
for (int id = 1; id <= M; ++id) {
int u = eu[per[id]], v = ev[per[id]];
int pu = fp(u), pv = fp(v);
if (pu != pv) {
++tot;
AnsU[tot] = u;
AnsV[tot] = v;
pa[pu] = pv;
iper[per[id]] = tot;
}
}
return tot == N - 1;
}
VI G[MN];
int bel[MN], scnt;
int dfn[MN], low[MN], dfc;
int stk[MN], top;
bool instk[MN];
void Tarjan(int u) {
dfn[u] = low[u] = ++dfc;
instk[stk[++top] = u] = true;
for (int v : G[u]) {
if (!dfn[v]) {
Tarjan(v);
low[u] = std::min(low[u], low[v]);
} else if (instk[v])
low[u] = std::min(low[u], dfn[v]);
}
if (low[u] == dfn[u]) {
++scnt;
while (true) {
int w = stk[top--];
instk[w] = false;
bel[w] = scnt;
// printf("bel[%d] = %d\n", w, scnt);
if (w == u)
break;
}
}
}
inline bool Solve() {
for (int i = 1; i <= 2 * (N - 1); ++i)
G[i].clear(), dfn[i] = low[i] = 0;
auto AddE = [&](int u, int tu, int v, int tv) -> void {
if (!u || !v || !iper[u] || !iper[v])
return ;
// printf("([(%d, %d) - (%d, %d)], %d) <---> ([(%d, %d) - (%d, %d)], %d)\n", 2 * x[eu[u]], 2 * y[eu[u]], 2 * x[ev[u]], 2 * y[ev[u]], tu, 2 * x[eu[v]], 2 * y[eu[v]], 2 * x[ev[v]], 2 * y[ev[v]], tv);
u = iper[u], v = iper[v];
G[u + (tu ? N - 1 : 0)].push_back(v + (tv ? 0 : N - 1));
G[v + (tv ? N - 1 : 0)].push_back(u + (tu ? 0 : N - 1));
};
for (int i = 1; i <= N; ++i) {
AddE(edir[i][0], 1, edir[i][1], 1);
AddE(edir[i][1], 0, edir[i][2], 1);
AddE(edir[i][2], 0, edir[i][3], 0);
AddE(edir[i][3], 1, edir[i][0], 0);
if (ndir[i][0] && ndir[i][1] && ndir[ndir[i][0]][1]) {
AddE(edir[i][0], 1, edir[ndir[i][1]][0], 0);
AddE(edir[i][1], 1, edir[ndir[i][0]][1], 0);
}
}
scnt = 0;
for (int u = 1; u <= 2 * (N - 1); ++u)
if (!dfn[u])
Tarjan(u);
for (int i = 1; i <= N - 1; ++i) {
if (bel[i] == bel[i + N - 1])
return false;
int d = bel[i + N - 1] < bel[i];
AnsA[i] = x[AnsU[i]] + x[AnsV[i]];
AnsB[i] = y[AnsU[i]] + y[AnsV[i]];
if (x[AnsU[i]] == x[AnsV[i]])
AnsA[i] += (d ? 1 : -1);
if (y[AnsU[i]] == y[AnsV[i]])
AnsB[i] += (d ? 1 : -1);
}
build(arr2vec(AnsU, N - 1, -1), arr2vec(AnsV, N - 1, -1), arr2vec(AnsA, N - 1), arr2vec(AnsB, N - 1));
return true;
}
int construct_roads(VI t_x, VI t_y) {
clock_t tstart = clock();
N = (int)t_x.size();
vec2arr(t_x, x);
vec2arr(t_y, y);
for (int i = 1; i <= N; ++i) {
x[i] /= 2;
y[i] /= 2;
mp[x[i]][y[i]] = i;
}
for (int i = 1; i <= N; ++i) {
for (int d = 0; d < 2; ++d) {
int nx = x[i] + dx[d];
int ny = y[i] + dy[d];
auto it = mp[nx].find(ny);
if (it != mp[nx].end()) {
++M;
eu[M] = i;
ev[M] = it -> second;
if (rng() & 1)
std::swap(eu[M], ev[M]);
ndir[i][d] = it->second;
ndir[it->second][d ^ 2] = i;
edir[i][d] = M;
edir[it->second][d ^ 2] = M;
}
}
}
for (int i = 1; i <= M; ++i)
per[i] = i;
if (!GenTree())
return 0;
if (Solve())
return 1;
while ((clock() - tstart) / (double)CLOCKS_PER_SEC < 2.7) {
GenTree();
if (Solve())
return 1;
}
return 0;
}
# | 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... |