Submission #839818

#TimeUsernameProblemLanguageResultExecution timeMemory
839818popovicirobertPalembang Bridges (APIO15_bridge)C++14
100 / 100
1614 ms40632 KiB
#include <bits/stdc++.h> using namespace std; constexpr long long INF = 1e18; constexpr int MAXC = (int) 1e9; struct SegTree { SegTree(int n) { data.resize(4 * n + 1); } void update(int node, int left, int right, int pos, long long value) { if (left == right) { data[node].first += value; data[node].second++; } else { int mid = (left + right) / 2; if (pos <= mid) update(2 * node, left, mid, pos, value); else update(2 * node + 1, mid + 1, right, pos, value); data[node].first = data[2 * node].first + data[2 * node + 1].first; data[node].second = data[2 * node].second + data[2 * node + 1].second; } } pair<long long, int> query(int node, int left, int right, int ql, int qr) { if (ql > qr) { return {0, 0}; } if (ql <= left && right <= qr) { return data[node]; } else { int mid = (left + right) / 2; pair<long long, int> L = {0, 0}, R = {0, 0}; if (ql <= mid) L = query(2 * node, left, mid, ql, qr); if (mid < qr) R = query(2 * node + 1, mid + 1, right, ql, qr); return {L.first + R.first, L.second + R.second}; } } vector<pair<long long, int>> data; }; struct Road { int x, y; }; auto normalize(const vector<Road>& roads) { vector<int> v; for (auto& road : roads) { v.push_back(road.x); v.push_back(road.y); } sort(v.begin(), v.end()); v.resize(unique(v.begin(), v.end()) - v.begin()); unordered_map<int, int> norm; for (int i = 0; i < (int)v.size(); i++) { norm[v[i]] = i + 1; } return norm; } void GetAnswers(vector<long long>& pref, vector<Road>& roads) { int n = (int)roads.size() - 1; for (int i = 1; i <= n; i++) { if (roads[i].x > roads[i].y) { swap(roads[i].x, roads[i].y); } // cerr << roads[i].x << " " << roads[i].y << " "; } // cerr << "\n"; pref.resize(n + 1, INF); pref[0] = 0; auto norm = normalize(roads); const int MAX_VALUE = norm.size(); vector<int> realValue(MAX_VALUE + 1); for (const auto& p : norm) { realValue[p.second] = p.first; } SegTree small(MAX_VALUE), large(MAX_VALUE); auto GetSplit = [&](int split) { auto SMALL = small.query(1, 1, MAX_VALUE, 1, split - 1); auto LARGE = large.query(1, 1, MAX_VALUE, split + 1, MAX_VALUE); return 2LL * realValue[split] * SMALL.second - SMALL.first + LARGE.first - 2LL * realValue[split] * LARGE.second; }; long long totalDiffSum = 0; for (int i = 1; i <= n; i++) { long long diff = roads[i].y - roads[i].x; totalDiffSum += diff; small.update(1, 1, MAX_VALUE, norm[roads[i].y], roads[i].x + roads[i].y + diff); large.update(1, 1, MAX_VALUE, norm[roads[i].x], roads[i].x + roads[i].y - diff); int split = 0; for (int step = 1 << 17; step; step >>= 1) { if (split + step < MAX_VALUE && GetSplit(split + step) >= GetSplit(split + step + 1)) { split += step; } } pref[i] = GetSplit(split + 1) + totalDiffSum + i; // cerr << realValue[split + 1] << " " << pref[i] << "\n"; } } int main() { #ifdef HOME ifstream cin("input.in"); ofstream cout("output.out"); #endif ios::sync_with_stdio(false); cin.tie(0), cout.tie(0); int k, n; cin >> k >> n; vector<Road> roads(1); long long sameSideAnswer = 0; for (int i = 1; i <= n; i++) { char side1, side2; int x, y; cin >> side1 >> x >> side2 >> y; if (side1 == side2) { sameSideAnswer += llabs(x - y); } else { roads.push_back({x, y}); } } n = (int)roads.size() - 1; sort(roads.begin() + 1, roads.end(), [](const Road& r1, const Road& r2) { return r1.x + r1.y < r2.x + r2.y; }); vector<long long> pref; GetAnswers(pref, roads); vector<long long> suff; for (int i = 1; i < n - i + 1; i++) { swap(roads[i], roads[n - i + 1]); } for (int i = 1; i <= n; i++) { auto& road = roads[i]; road.x = MAXC - road.x; road.y = MAXC - road.y; } GetAnswers(suff, roads); long long differentSideAnswer = pref[n]; if (k == 2) { for (int i = 0; i <= n; i++) { differentSideAnswer = min(differentSideAnswer, pref[i] + suff[n - i]); } } cout << sameSideAnswer + differentSideAnswer << "\n"; 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...
#Verdict Execution timeMemoryGrader output
Fetching results...