제출 #1340726

#제출 시각아이디문제언어결과실행 시간메모리
1340726NikoBaoticČVENK (COI15_cvenk)C++20
100 / 100
842 ms154392 KiB
#include "bits/stdc++.h"

using namespace std;

typedef long long ll;
typedef pair<ll, ll> pii;

#define all(x) x.begin(), x.end()
#define sz(x) ((int) ((x).size()))
#define pb push_back
#define F first
#define S second
#define FIO ios_base::sync_with_stdio(false); cin.tie(0)

const int N = 1e5 + 10;
const int B = 20;

ll reduce(ll x, ll m) {
	if (m == 0) return 0;
	return (((1 << __builtin_ctz(m)) - 1) & x) ^ x;
}

int n;
pii p[N];
map<pii, int> oc;

int vel;
vector<int> chi[N * B];
int par[N * B];
pii pos[N * B];
ll num[N * B];
ll dis[N * B];
map<pii, int> conv;
ll ans;

int get(pii x) {
	auto iter = conv.find(x);

	if (iter != conv.end()) return iter->S;

	conv[x] = ++vel;
	pos[vel] = x;

	return vel;
}

int add(pii x) {
	if (x.F == 0 and x.S == 0) return 1;

	auto iter = conv.find(x);
	if (iter != conv.end()) return iter->S;

	ll nx = reduce(x.F, x.S);
	ll ny = reduce(x.S, x.F);

	int u = add(make_pair(nx, ny));
	int node = get(x);

	chi[u].pb(node);
	par[node] = u;
	
	return node;
}

void format(int node) {
	vector<pii> f;
	vector<pii> s;

	for (int x : chi[node]) {
		if (pos[node].F == pos[x].F) f.pb({pos[x].S, x});
		else s.pb({pos[x].F, x});
	}

	chi[node].clear();

	sort(all(f));
	sort(all(s));

	int last = node;

	for (pii x : f) {
		chi[last].pb(x.S);	
		par[x.S] = last;
		last = x.S;
	}

	last = node;
	
	for (pii x : s) {
		chi[last].pb(x.S);
		par[x.S] = last;
		last = x.S;
	}

	for (int x : chi[node]) {
		format(x);
	}
}

ll man(pii x, pii y) {
	return abs(x.F - y.F) + abs(x.S - y.S);
}

void calc(int node) {
	num[node] = oc[pos[node]];
	for (int x : chi[node]) {
		calc(x);
		num[node] += num[x];
		dis[node] += dis[x] + man(pos[node], pos[x]) * num[x];
	}
}

void run(int node, ll now) {
	ans = min(ans, now);

	for (int x : chi[node]) {
		run(x, now + man(pos[node], pos[x]) * (n - num[x] * 2));
	}
}

int main() {
	FIO;

	ans = LONG_LONG_MAX;

	cin >> n;

	for (int i = 0; i < n; i++) {
		cin >> p[i].F >> p[i].S;
		oc[p[i]]++;
	}

	get({0LL, 0LL});

	for (int i = 0; i < n; i++) {
		add(p[i]);
	}

	format(1);
	calc(1);
	run(1, dis[1]);

	cout << ans << endl;

	return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...