結果
| 問題 |
No.3303 Heal Slimes 2
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2025-07-09 06:51:23 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 494 ms / 4,000 ms |
| コード長 | 3,948 bytes |
| コンパイル時間 | 2,162 ms |
| コンパイル使用メモリ | 209,516 KB |
| 実行使用メモリ | 7,720 KB |
| 最終ジャッジ日時 | 2025-10-21 10:21:39 |
| 合計ジャッジ時間 | 9,843 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 32 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
template <typename T>
struct BinaryIndexedTree{
int N;
std::vector<T> BIT;
BinaryIndexedTree(const int N) : N(N), BIT(N + 1, 0){
}
T get(int i){
return sum(i + 1) - sum(i);
}
void add(int i, T x){
i++;
while(i <= N){
BIT[i] += x;
i += i & -i;
}
}
T sum(int i) const {
T ans = 0;
while(i > 0){
ans += BIT[i];
i -= i & -i;
}
return ans;
}
T sum(int L, int R) const {
return sum(R) - sum(L);
}
int lower_bound(T x) const {
if(x <= 0){
return 0;
} else{
int v = 0, r = 1;
while(r < N) r = r << 1;
for(int len = r; len > 0; len = len >> 1){
if(v + len < N && BIT[v + len] < x){
x -= BIT[v + len];
v += len;
}
}
return v;
}
}
int upper_bound(T x) const {
if(x < 0){
return 0;
} else{
int v = 0, r = 1;
while(r <= N) r = r << 1;
for(int len = r; len > 0; len = len >> 1){
if(v + len <= N && BIT[v + len] <= x){
x -= BIT[v + len];
v += len;
}
}
return v;
}
}
T operator [](int i) const {
return sum(i, i + 1);
}
};
template <typename T>
struct compress{
std::vector<T> sorted;
std::vector<int> compressed;
compress(const std::vector<T> &vec){
int n = vec.size();
compressed.resize(n);
for(T x : vec){
sorted.emplace_back(x);
}
std::sort(sorted.begin(), sorted.end());
sorted.erase(std::unique(sorted.begin(), sorted.end()), sorted.end());
for(int i = 0; i < n; ++i){
compressed[i] = std::lower_bound(sorted.begin(), sorted.end(), vec[i]) - sorted.begin();
}
}
int get(const T &x) const{
return std::lower_bound(sorted.begin(), sorted.end(), x) - sorted.begin();
}
T inv(const int x) const{
return sorted[x];
}
size_t size() const{
return sorted.size();
}
std::vector<int> getCompressed() const{
return compressed;
}
};
const long long INF = 1LL << 60;
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, k; cin >> n >> k;
long long d; cin >> d;
vector<long long> h(n);
for(int i = 0; i < n; i++){
cin >> h[i];
}
compress<long long> comp(h);
vector<int> hc = comp.getCompressed();
BinaryIndexedTree<long long> cnt(comp.size()), val(comp.size());
for(int i = 0; i < k - 1; i++){
cnt.add(hc[i], 1);
val.add(hc[i], h[i]);
}
long long ans = INF;
auto idxl = [&](long long x){
return comp.get(x);
};
auto idxr = [&](long long x){
return upper_bound(comp.sorted.begin(), comp.sorted.end(), x) - comp.sorted.begin();
};
auto f = [&](long long x){
long long res = 0;
res += cnt.sum(0, idxr(x)) * x - val.sum(0, idxr(x));
res += val.sum(idxl(x + d), comp.size()) - cnt.sum(idxl(x + d), comp.size()) * (x + d);
return res;
};
long long maxval = 1e9;
for(int i = k - 1; i < n; i++){
cnt.add(hc[i], 1);
val.add(hc[i], h[i]);
int ok = 0, ng = maxval + 1;
while(abs(ok - ng) > 1){
int mid = (ok + ng) / 2;
if(cnt.sum(idxl(mid + d), comp.size()) - cnt.sum(0, idxr(mid)) >= 0){
ok = mid;
} else {
ng = mid;
}
}
ans = min(ans, f(ok));
ans = min(ans, f(ok + 1));
cnt.add(hc[i - k + 1], -1);
val.add(hc[i - k + 1], -h[i - k + 1]);
}
cout << ans << endl;
return 0;
}