結果
| 問題 | No.738 平らな農地 |
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2026-02-23 20:54:49 |
| 言語 | C++14 (gcc 15.2.0 + boost 1.89.0) |
| 結果 |
AC
|
| 実行時間 | 238 ms / 2,000 ms |
| コード長 | 2,819 bytes |
| 記録 | |
| コンパイル時間 | 1,196 ms |
| コンパイル使用メモリ | 95,380 KB |
| 実行使用メモリ | 66,644 KB |
| 最終ジャッジ日時 | 2026-02-23 20:55:02 |
| 合計ジャッジ時間 | 12,670 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 5 |
| other | AC * 87 |
コンパイルメッセージ
main.cpp: In function 'int main()':
main.cpp:89:14: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17' [-Wc++17-extensions]
89 | auto [sum1, sz1] = sgt.Query(sgt.rt, 1, V, 1, mid - 1);
| ^
main.cpp:90:14: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17' [-Wc++17-extensions]
90 | auto [sum2, sz2] = sgt.Query(sgt.rt, 1, V, mid + 1, V);
| ^
ソースコード
#include <iostream>
#include <cstdio>
using namespace std;
typedef long long LL;
typedef pair<LL, LL> PLL;
const int N = 100010, V = 1000000010;
const LL INF = 9e18;
struct Node {
int l, r, sz;
LL sum;
};
int n, k, a[N];
LL ans;
// 动态开点权值线段树
// 每次求中位数,用树上二分
struct SegTree {
int rt, idx;
Node seg[N * 100];
void PushUp(int u) {
if (!seg[u].l) seg[u].l = ++idx;
if (!seg[u].r) seg[u].r = ++idx;
seg[u].sum = seg[seg[u].l].sum + seg[seg[u].r].sum;
seg[u].sz = seg[seg[u].l].sz + seg[seg[u].r].sz;
}
void Add(int& u, int ul, int ur, int x, int v) {
if (!u) u = ++idx;
if (ul == ur) {
seg[u].sz += v;
seg[u].sum += 1LL * x * v;
return;
}
int mid = ul + ur >> 1;
if (mid >= x) Add(seg[u].l, ul, mid, x, v);
else Add(seg[u].r, mid + 1, ur, x, v);
PushUp(u);
}
int Kth(int u, int ul, int ur, int kth) {
if (ul == ur) return ul;
int mid = ul + ur >> 1;
if (seg[seg[u].l].sz >= kth) {
return Kth(seg[u].l, ul, mid, kth);
} else {
return Kth(seg[u].r, mid + 1, ur, kth - seg[seg[u].l].sz);
}
}
PLL Query(int u, int ul, int ur, int l, int r) {
if (l > r) return { 0LL, 0LL };
if (!u) return { 0LL, 0LL };
if (l <= ul && ur <= r) return { seg[u].sum, seg[u].sz };
int mid = ul + ur >> 1;
PLL ret = { 0LL, 0LL };
if (mid >= l) {
PLL cur = Query(seg[u].l, ul, mid, l, r);
ret.first += cur.first;
ret.second += cur.second;
}
if (mid + 1 <= r) {
PLL cur = Query(seg[u].r, mid + 1, ur, l, r);
ret.first += cur.first;
ret.second += cur.second;
}
return ret;
}
};
SegTree sgt;
int main() {
// freopen("farmland.in", "r", stdin);
// freopen("farmland.out", "w", stdout);
scanf("%d%d", &n, &k);
for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);
ans = INF;
for (int i = 1; i <= k; ++i) sgt.Add(sgt.rt, 1, V, a[i], 1);
for (int i = 1; i <= n - k + 1; ++i) {
if (i >= 2) {
sgt.Add(sgt.rt, 1, V, a[i - 1], -1);
sgt.Add(sgt.rt, 1, V, a[i + k - 1], 1);
}
int mid = sgt.Kth(sgt.rt, 1, V, (k + 1) / 2);
auto [sum1, sz1] = sgt.Query(sgt.rt, 1, V, 1, mid - 1);
auto [sum2, sz2] = sgt.Query(sgt.rt, 1, V, mid + 1, V);
if (sz1 == 0 && sz2 == 0) ans = min(ans, 0LL);
else if (sz1 == 0) ans = min(ans, sum2 - sz2 * mid);
else if (sz2 == 0) ans = min(ans, sz1 * mid - sum1);
else ans = min(ans, (sz1 * mid - sum1) + (sum2 - sz2 * mid));
}
printf("%lld\n", ans);
return 0;
}