結果
| 問題 | No.489 株に挑戦 |
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2017-02-25 01:01:30 |
| 言語 | C++11(old_compat) (gcc 12.4.0 + boost 1.89.0) |
| 結果 |
AC
|
| 実行時間 | 56 ms / 1,000 ms |
| コード長 | 2,597 bytes |
| 記録 | |
| コンパイル時間 | 1,592 ms |
| コンパイル使用メモリ | 173,448 KB |
| 実行使用メモリ | 7,844 KB |
| 最終ジャッジ日時 | 2026-03-08 16:09:20 |
| 合計ジャッジ時間 | 3,155 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 35 |
コンパイルメッセージ
main.cpp: In function ‘int main()’:
main.cpp:80:21: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
80 | int n, d, k; scanf("%d%d%d", &n, &d, &k);
| ~~~~~^~~~~~~~~~~~~~~~~~~~~~
main.cpp:83:10: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
83 | scanf("%d", &x[i]);
| ~~~~~^~~~~~~~~~~~~
ソースコード
#include <iostream>
#include <algorithm>
#include <tuple>
using namespace std;
using i64 = long long;
class SegTree {
int n;
vector<int> v;
vector<int> p; // 場所
pair<int, int> query(int a, int b, int k, int l, int r);
public:
const int INIT_VAL = 0;
SegTree(int n);
SegTree(const vector<int> &w);
static int min_pow2(const int n); // n以上の最小の "2の冪乗"
static int calc_size(const int n); // 要素数 n の配列をセグメントツリーにするときのサイズ (min_pow2(n) x 2) を計算する
void update(int i, int val); // 配列 w の i 番目 (0-indexed) を val にする。
pair<int, int> query(int a, int b); // [a, b) の範囲
};
SegTree::SegTree(int n) : n(n), v(n, INIT_VAL) { v[0] = -1; }
SegTree::SegTree(const vector<int> &w) {
int m = w.size();
n = calc_size(m);
v.assign(n, INIT_VAL);
p.assign(n, -1);
v[0] = -1;
p[0] = -1;
for(int i=0; i<m; ++i) {
update(i, w[i]);
}
}
void SegTree::
update(int i, int val) {
i += n / 2;
v[i] = val;
p[i] = i;
while(true) {
i >>= 1;
if(i == 0) { break; }
if(v[i*2] < v[i*2+1]) {
v[i] = v[i*2+1];
p[i] = p[i*2+1];
} else {
v[i] = v[i*2];
p[i] = p[i*2];
}
}
}
pair<int, int> SegTree::
query(int a, int b, int k, int l, int r) {
// [a, b) と [l, r) が交差しないとき
if(r <= a || b <= l) { return make_pair(-1, INIT_VAL); }
// [a, b) が [l, r) を完全に含んでいるとき
if(a <= l && r <= b) {
return make_pair(p[k], v[k]);
}
int pl, vl, pr, vr;
tie(pl, vl) = query(a, b, 2*k, l, (l+r)/2),
tie(pr, vr) = query(a, b, 2*k+1, (l+r)/2, r);
if(vl < vr) {
return make_pair(pr, vr);
}
return make_pair(pl, vl);
}
// [a, b) の範囲 (a, b は 0-indexed)
pair<int, int> SegTree::
query(int a, int b) {
return query(a, b, 1, 0, n >> 1);
}
int SegTree::min_pow2(const int n) { int m = 1; while(m < n) { m <<= 1; } return m; }
int SegTree::calc_size(const int n) { return min_pow2(n) << 1; }
int main(void) {
int n, d, k; scanf("%d%d%d", &n, &d, &k);
vector<int> x(n); // x[n]
for(int i=0; i<n; ++i) {
scanf("%d", &x[i]);
}
SegTree tree(x);
int p2 = SegTree::min_pow2(n);
int max_dif = 0;
int a = -1, b = -1;
for(int i=0; i<n; ++i) {
int j, maxi; tie(j, maxi) = tree.query(i, min(i+d+1, n));
j -= p2;
int dif = maxi - x[i];
if(max_dif < dif) {
max_dif = dif;
a = i;
b = j;
}
}
if(max_dif == 0) {
puts("0");
return 0;
}
i64 amount = i64(max_dif) * k;
printf("%lld\n%d %d\n", amount, a, b);
return 0;
}