Submission #1267561

#TimeUsernameProblemLanguageResultExecution timeMemory
1267561canhnam357Krov (COCI17_krov)C++20
140 / 140
609 ms9196 KiB
#include <bits/stdc++.h> using namespace std; #define int long long #define all(x) x.begin(), x.end() struct fenwick { int n; vector<int> bit; fenwick() {} fenwick(int n) { this->n = n + 5; bit.resize(n + 5); } void add(int pos, int val) { while (pos < n) { bit[pos] += val; pos += pos & -pos; } } int get(int pos) { if (pos < 0) return 0; int ans = 0; while (pos) { ans += bit[pos]; pos -= pos & -pos; } return ans; } int get(int l, int r) { if (l > r) return 0; return get(r) - get(l - 1); } }; int32_t main() { ios_base::sync_with_stdio(0); cin.tie(0); int n; cin >> n; vector<int> a(n), cc; for (int i = 0; i < n; i++) { cin >> a[i]; cc.push_back(a[i] + i); cc.push_back(a[i] - i); } sort(all(cc)); cc.erase(unique(all(cc)), cc.end()); int m = cc.size(); auto get_pos = [&](int pos) { if (pos > cc.back()) return m + 1; return (int)(upper_bound(all(cc), pos) - cc.begin()); }; int ans = LLONG_MAX; /* left : a[j] - (a[i] - (i - j)) = (a[j] - j) - (a[i] - i) right : a[j] - (a[i] - (j - i)) = (a[j] + j) - (a[i] + i) */ /* Cố định cột i là đỉnh, tìm kiếm tam phân để tìm ra chiều cao tối thiểu chi phí thay đổi */ fenwick occ_left(m), sum_left(m), occ_right(m), sum_right(m); for (int i = 0; i < n; i++) { int pos = get_pos(a[i] + i); occ_right.add(pos, 1); sum_right.add(pos, a[i] + i); } auto f = [&](int h, int i) { int cost = 0; { int p = get_pos(h - i); int k = h - i; cost += occ_left.get(p) * k - sum_left.get(p); cost += sum_left.get(p + 1, m) - k * occ_left.get(p + 1, m); } { int p = get_pos(h + i); int k = h + i; cost += occ_right.get(p) * k - sum_right.get(p); cost += sum_right.get(p + 1, m) - k * occ_right.get(p + 1, m); } return cost; }; auto g = [&](int h, int i) { int cost = 0; for (int j = 0; j < i; j++) { cost += abs(a[j] - j - (h - i)); } for (int j = i; j < n; j++) { cost += abs(a[j] + j - (h + i)); } return cost; }; for (int i = 0; i < n; i++) { int left_bound = max(i + 1, n - i); int right_bound = 1e9; // cout << "POS " << i << '\n'; // for (int j = left_bound; j <= 10; j++) { // cout << j << ' ' << f(j, i) << ' ' << g(j, i) << '\n'; // } int l = left_bound, r = right_bound; while (r - l > 1) { int mid = (l + r) >> 1; if (f(mid, i) <= f(mid - 1, i)) l = mid; else r = mid; } ans = min({ans, f(left_bound, i), f(right_bound, i), f(l, i)}); int pos = get_pos(a[i] - i); occ_left.add(pos, 1); sum_left.add(pos, a[i] - i); pos = get_pos(a[i] + i); occ_right.add(pos, -1); sum_right.add(pos, -a[i] - i); } cout << ans << '\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...
#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...