結果
| 問題 | No.738 平らな農地 |
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2024-12-01 11:34:15 |
| 言語 | C++23 (gcc 13.3.0 + boost 1.89.0) |
| 結果 |
AC
|
| 実行時間 | 856 ms / 2,000 ms |
| コード長 | 3,517 bytes |
| 記録 | |
| コンパイル時間 | 3,560 ms |
| コンパイル使用メモリ | 257,272 KB |
| 実行使用メモリ | 54,272 KB |
| 最終ジャッジ日時 | 2024-12-01 11:34:51 |
| 合計ジャッジ時間 | 35,761 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 5 |
| other | AC * 87 |
ソースコード
#ifndef LOCAL
#include <bits/stdc++.h>
using namespace std;
#define debug(...) (void(0))
#else
#include "algo/debug.h"
#endif
template <class T>
struct MergeSortTree {
private:
int N;
int sz;
T mn, mx;
std::vector<std::vector<T>> dat;
std::vector<std::vector<T>> pref;
int LB(const std::vector<T>& v, const T& x) const {
return std::distance(v.begin(), std::lower_bound(v.begin(), v.end(), x));
}
public:
MergeSortTree() = default;
MergeSortTree(const std::vector<T>& v) : N((int)v.size()) {
mn = std::numeric_limits<T>::max();
mx = std::numeric_limits<T>::lowest();
sz = (int)std::bit_ceil((unsigned int)N);
dat.assign(2 * sz, {});
pref.assign(2 * sz, {0});
for (int i = 0; i < N; i++) {
dat[i + sz].push_back(v[i]);
pref[i + sz].push_back(v[i]);
mn = std::min(mn, v[i]);
mx = std::max(mx, v[i]);
}
for (int i = sz - 1; i >= 1; i--) {
dat[i].resize(dat[2 * i].size() + dat[2 * i + 1].size());
std::merge(dat[2 * i].begin(), dat[2 * i].end(), dat[2 * i + 1].begin(), dat[2 * i + 1].end(), dat[i].begin());
pref[i].resize(dat[i].size() + 1);
for (unsigned j{}; j < dat[i].size(); j++) {
pref[i][j + 1] += pref[i][j] + dat[i][j];
}
}
};
int count_lt(int l, int r, const T& x) const {
assert(0 <= l && l <= r && r <= N);
l += sz;
r += sz;
int ans = 0;
while (l < r) {
if (l & 1) ans += LB(dat[l++], x);
if (r & 1) ans += LB(dat[--r], x);
l >>= 1;
r >>= 1;
}
return ans;
}
int count_le(int l, int r, const T& x) const { return count_lt(l, r, x + 1); }
int count_gt(int l, int r, const T& x) const { return r - l - count_le(l, r, x); }
int count_ge(int l, int r, const T& x) const { return r - l - count_lt(l, r, x); }
T kth(int l, int r, const T& k) const {
T lo = mn, hi = mx + T{1};
while (hi > lo + 1) {
T mi = (lo + hi) >> 1;
(count_lt(l, r, mi) <= k ? lo : hi) = mi;
}
return lo;
}
int64_t Solve(int l, int r, int K) const {
int64_t val = kth(l, r, K / 2);
int64_t cnt_lt = count_lt(l, r, val);
int64_t cnt_ge = r - l - cnt_lt;
l += sz;
r += sz;
int64_t sum_lt = 0;
int64_t sum_all = 0;
while (l < r) {
if (l & 1) {
int k = LB(dat[l], val);
sum_lt += pref[l][k];
sum_all += pref[l][dat[l].size()];
l++;
}
if (r & 1) {
r--;
int k = LB(dat[r], val);
sum_lt += pref[r][k];
sum_all += pref[r][dat[r].size()];
}
l >>= 1;
r >>= 1;
}
int64_t sum_ge = sum_all - sum_lt;
return val * (cnt_lt - cnt_ge) + sum_ge - sum_lt;
}
};
void solve() {
int N, K;
cin >> N >> K;
vector<int64_t> A(N);
for (int i = 0; i < N; i++) cin >> A[i];
MergeSortTree<int64_t> freq(A);
int64_t ans = 1e18;
for (int i = 0; i + K <= N; i++) {
ans = min(ans, freq.Solve(i, i + K, K));
}
cout << ans << endl;
}
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int tt = 1;
// std::cin >> tt;
while (tt--) {
solve();
}
}