#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pii pair <int , int>
#define X first
#define Y second
#define F first
#define S second
#define mp make_pair
#define all(v) v.begin(), v.end()
const int N = 30, M = 2e5 + 5;
int pw[N], x[M], y[M], cnt[M], sz[M], dw[M], up[M];
vector <pii> P, g[M];
map <pii, int> Label;
int Zone(pii p, int n) {
if (p.X >= pw[n-1]) return 2;
if (p.Y >= pw[n-1]) return 1;
return 0;
}
void dfs_order(vector <pii> &vec, int n = N) {
if (n == 0 || vec.size() == 0) return ;
vector <pii> v[3];
for (pii p : vec) {
int z = Zone(p, n);
if (z == 1) v[1].push_back({p.X, p.Y - pw[n-1]});
if (z == 2) v[2].push_back({p.X - pw[n-1], p.Y});
if (z == 0) v[0].push_back(p);
}
vec.clear();
dfs_order(v[0], n - 1), dfs_order(v[1], n - 1), dfs_order(v[2], n - 1);
int pnt = 0;
while (pnt < v[0].size() && v[0][pnt].X == 0) vec.push_back(v[0][pnt++]);
for (pii p : v[1]) vec.push_back({p.X, p.Y + pw[n-1]});
while (pnt < v[0].size()) vec.push_back(v[0][pnt++]);
for (pii p : v[2]) vec.push_back({p.X + pw[n-1], p.Y});
}
pii LCA(pii u, pii v, int n = N) {
if (n == 0) return {0, 0};
int zu = Zone(u, n), zv = Zone(v, n);
if (zu > zv) swap(u, v), swap(zu, zv);
if (zu == 1 && zv == 2) return {0, 0};
if (zu == 2 && zv == 2) {
pii A = LCA({u.X - pw[n-1], u.Y}, {v.X - pw[n-1], v.Y}, n - 1);
return {A.X + pw[n - 1], A.Y};
}
if (zu == 1 && zv == 1) {
pii A = LCA({u.X, u.Y - pw[n - 1]}, {v.X, v.Y - pw[n - 1]}, n - 1);
return {A.X, A.Y + pw[n - 1]};
}
if (zu == 0 && zv == 0) return LCA(u, v, n - 1);
if (zv == 2) return LCA(u, {pw[n - 1] - 1, 0});
if (zv == 1) return LCA(u, {0, pw[n - 1] - 1});
}
int DIS(pii u, pii v, int n = N) {
if (n == 0) return 0;
int zu = Zone(u, n), zv = Zone(v, n);
if (zu > zv) swap(u, v), swap(zu, zv);
if (zu == 1 && zv == 2) return u.X + u.Y + v.X + v.Y;
if (zu == 2 && zv == 2) return DIS({u.X - pw[n-1], u.Y}, {v.X - pw[n-1], v.Y}, n - 1);
if (zu == 1 && zv == 1) return DIS({u.X, u.Y - pw[n-1]}, {v.X, v.Y - pw[n-1]}, n - 1);
if (zu == 0 && zv == 0) return DIS(u, v, n - 1);
if (zv == 2) return DIS(u, {pw[n - 1] - 1, 0}) + v.X + v.Y - pw[n-1] + 1;
if (zv == 1) return DIS(u, {0, pw[n - 1] - 1}) + v.X + v.Y - pw[n-1] + 1;
}
void dfs_down(int v) {
sz[v] = cnt[v];
for (pii e : g[v]) dfs_down(e.F), dw[v] += e.S * sz[e.F] + dw[e.F], sz[v] += sz[e.F];
}
void dfs_up(int v, int p = -1, int w = 0) {
if (p != -1)
up[v] = dw[p] + up[p] + (sz[0] - sz[v]) * w - dw[v] - sz[v] * w;
for (pii e : g[v]) dfs_up(e.F, v, e.S);
}
int32_t main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
for (int i = 0; i < N; i++) pw[i] = 1<<i;
int n; cin >> n, P.resize(n);
for (int i = 0; i < n; i++) {
cin >> x[i] >> y[i];
P[i].X = x[i], P[i].Y = y[i];
}
if (n == 2) return cout << DIS(P[0], P[1]) << "\n", 0;
dfs_order(P);
for (int i = 1; i < n; i++) P.push_back(LCA(P[i - 1], P[i]));
P.push_back(LCA(P[0], P[n - 1]));
dfs_order(P);
P.resize(unique(all(P)) - P.begin());
for (int i = 0; i < P.size(); i++) Label[P[i]] = i;
for (int i = 0; i < n; i++) cnt[Label[{x[i], y[i]}]]++;
vector <int> s;
s.push_back(0);
for (int v = 1; v < P.size(); v++) {
while (LCA(P[s.back()], P[v]) != P[s.back()]) s.pop_back();
g[s.back()].push_back(mp(v, DIS(P[s.back()], P[v])));
s.push_back(v);
}
dfs_down(0), dfs_up(0);
int ans = 1e18;
for (int i = 0; i < P.size(); i++) ans = min(ans, dw[i] + up[i]);
cout << ans << "\n";
}
Compilation message
cvenk.cpp: In function 'void dfs_order(std::vector<std::pair<long long int, long long int> >&, long long int)':
cvenk.cpp:34:16: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
while (pnt < v[0].size() && v[0][pnt].X == 0) vec.push_back(v[0][pnt++]);
~~~~^~~~~~~~~~~~~
cvenk.cpp:36:16: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
while (pnt < v[0].size()) vec.push_back(v[0][pnt++]);
~~~~^~~~~~~~~~~~~
cvenk.cpp: In function 'int32_t main()':
cvenk.cpp:92:23: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
for (int i = 0; i < P.size(); i++) Label[P[i]] = i;
~~^~~~~~~~~~
cvenk.cpp:96:23: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
for (int v = 1; v < P.size(); v++) {
~~^~~~~~~~~~
cvenk.cpp:103:23: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
for (int i = 0; i < P.size(); i++) ans = min(ans, dw[i] + up[i]);
~~^~~~~~~~~~
cvenk.cpp: In function 'std::pair<long long int, long long int> LCA(std::pair<long long int, long long int>, std::pair<long long int, long long int>, long long int)':
cvenk.cpp:55:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
cvenk.cpp: In function 'long long int DIS(std::pair<long long int, long long int>, std::pair<long long int, long long int>, long long int)':
cvenk.cpp:66:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
7 ms |
4992 KB |
Output is correct |
2 |
Correct |
7 ms |
4992 KB |
Output is correct |
3 |
Correct |
7 ms |
5120 KB |
Output is correct |
4 |
Correct |
7 ms |
4992 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
9 ms |
5120 KB |
Output is correct |
2 |
Correct |
9 ms |
5120 KB |
Output is correct |
3 |
Correct |
8 ms |
5120 KB |
Output is correct |
4 |
Correct |
8 ms |
5120 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
259 ms |
85404 KB |
Output is correct |
2 |
Correct |
260 ms |
85084 KB |
Output is correct |
3 |
Correct |
225 ms |
88776 KB |
Output is correct |
4 |
Correct |
251 ms |
90316 KB |
Output is correct |
5 |
Correct |
233 ms |
88096 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1303 ms |
33528 KB |
Output is correct |
2 |
Correct |
1341 ms |
33412 KB |
Output is correct |
3 |
Correct |
741 ms |
27932 KB |
Output is correct |
4 |
Correct |
757 ms |
25008 KB |
Output is correct |
5 |
Correct |
749 ms |
24788 KB |
Output is correct |