結果
| 問題 |
No.1495 パンの仕入れ
|
| コンテスト | |
| ユーザー |
akakimidori
|
| 提出日時 | 2021-03-31 14:04:04 |
| 言語 | Rust (1.83.0 + proconio) |
| 結果 |
AC
|
| 実行時間 | 104 ms / 2,000 ms |
| コード長 | 2,374 bytes |
| コンパイル時間 | 12,713 ms |
| コンパイル使用メモリ | 375,324 KB |
| 実行使用メモリ | 9,716 KB |
| 最終ジャッジ日時 | 2024-12-16 05:43:04 |
| 合計ジャッジ時間 | 16,577 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 46 |
ソースコード
const MAX_T: i64 = 100;
const MAX_N: i64 = 200_000;
const MAX_M: i64 = 200_000;
const MAX_K: i64 = 1_000_000_000;
const MAX_Y: i64 = 1_000_000_000;
fn read() -> Vec<(usize, i64, Vec<(usize, i64)>)> {
let mut s = String::new();
use std::io::Read;
std::io::stdin().read_to_string(&mut s).unwrap();
let mut it = s.trim().split_whitespace();
let mut next = |l: i64, r: i64| {
let v = it.next().unwrap().parse::<i64>().unwrap();
assert!(l <= v && v <= r);
v
};
let t = next(1, MAX_T) as usize;
let mut sum_n = 0;
let mut sum_m = 0;
let mut test = vec![];
for _ in 0..t {
let n = next(1, MAX_N - sum_n) as usize;
let m = next(1, MAX_M - sum_m) as usize;
let k = next(1, MAX_K);
let mut p = vec![(0usize, 0i64); m];
for p in p.iter_mut() {
p.0 = (next(1, n as i64) - 1) as usize;
p.1 = next(1, MAX_Y);
}
assert!(
m.saturating_mul(k.max(p.iter().map(|p| p.1).max().unwrap()) as usize)
<= 10usize.pow(18)
);
test.push((n, k, p));
sum_n += n as i64;
sum_m += m as i64;
}
test
}
fn solve(n: usize, k: i64, p: &[(usize, i64)]) -> i64 {
let mut dp = vec![(0, 0, 0); n];
for &(x, y) in p.iter() {
let po = &mut dp[x];
po.0 += y * y;
po.1 -= 2 * y;
po.2 += 1;
}
let eval = |m: i64| -> (i64, i64) {
let mut cnt = 0;
let mut cost = 0;
for &(c, b, a) in dp.iter() {
cost += c;
if a > 0 {
let x = ((m - (b - a)).div_euclid(2 * a)).max(0);
cnt += x;
cost += 2 * a * (x + 1) * x / 2 + (b - a) * x;
} else if m >= 0 {
cnt += k;
}
}
(cnt, cost)
};
let mut ng = dp.iter().map(|&(_, b, a)| 2 * a + b - a - 1).min().unwrap();
let mut ok = dp.iter().map(|&(_, b, a)| 2 * a * k + b - a).min().unwrap();
while ok - ng > 1 {
let mid = (ok + ng) / 2;
if eval(mid).0 >= k {
ok = mid;
} else {
ng = mid;
}
}
let (x, y) = eval(ok);
let ans = y - ok * (x - k);
ans
}
fn main() {
let test = read();
for (n, k, p) in test {
let ans = solve(n, k, &p);
println!("{}", ans);
}
}
akakimidori