結果
| 問題 |
No.2390 Udon Coupon (Hard)
|
| コンテスト | |
| ユーザー |
👑 |
| 提出日時 | 2023-06-30 00:24:38 |
| 言語 | Rust (1.83.0 + proconio) |
| 結果 |
AC
|
| 実行時間 | 35 ms / 2,000 ms |
| コード長 | 2,741 bytes |
| コンパイル時間 | 12,563 ms |
| コンパイル使用メモリ | 379,628 KB |
| 実行使用メモリ | 5,248 KB |
| 最終ジャッジ日時 | 2024-10-06 01:30:58 |
| 合計ジャッジ時間 | 12,816 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 47 |
ソースコード
// O(A^2)解法
fn solve(n: u64, ab: &[(u64, u64); 3]) -> u64 {
assert!(n > 0 && n <= 10_0000_0000_0000);
assert!(ab
.iter()
.all(|&(a, b)| a > 0 && a <= 100000 && b > 0 && b.saturating_mul(n / a) <= (1u64 << 61)));
let co_solve = |n: u64, ab: &[(u64, u64); 3]| -> u64 {
let [(a0, b0), (a1, b1), (a2, b2)] = *ab;
// a0inv = ceil(2^63 / a0)
let a0inv = ((1u64 << 63) - 1) / a0 + 1;
let mut r = 0;
for (i, di) in (0..a0).zip((0..=n).rev().step_by(a1 as usize)) {
for (j, dj) in (0..a0).zip((0..=di).rev().step_by(a2 as usize)) {
// 準定数を除数とする除算の定数倍高速化
// 0 < a0 <= 10^5, 0 <= d <= n <= 10^13 < 2^63/10^5 <= 2^63 / a0 <= ceil(2^63 / a0) = a0inv < ((2^63 / a0) + 1)
// quot = floor((n - (i * a1 + j * a2)) / a0) = floor(d / a0) = floor((d * 2) * ceil(2^63 / a0) / 2^64) - (0 または 1)
let qsim = ((((dj * 2) as u128) * (a0inv as u128)) >> 64) as u64;
let quot = qsim - u64::from(dj.checked_sub(qsim * a0).is_none());
debug_assert_eq!(dj / a0, quot);
r.chmax(quot * b0 + i * b1 + j * b2);
}
}
r
};
[
co_solve(n, &[ab[0], ab[1], ab[2]]),
co_solve(n, &[ab[1], ab[2], ab[0]]),
co_solve(n, &[ab[2], ab[0], ab[1]]),
]
.iter()
.copied()
.max()
.unwrap()
}
fn main() {
let tins = std::time::Instant::now();
let mut input = String::with_capacity(1024);
std::io::Read::read_to_string(&mut std::io::stdin(), &mut input).unwrap();
let mut tokens = input.split_whitespace();
let n = tokens.next().unwrap().parse::<u64>().unwrap();
let ab = [
(
tokens.next().unwrap().parse::<u64>().unwrap(),
tokens.next().unwrap().parse::<u64>().unwrap(),
),
(
tokens.next().unwrap().parse::<u64>().unwrap(),
tokens.next().unwrap().parse::<u64>().unwrap(),
),
(
tokens.next().unwrap().parse::<u64>().unwrap(),
tokens.next().unwrap().parse::<u64>().unwrap(),
),
];
eprint!(
"{}\n{} {}\n{} {}\n{} {}\n",
n, ab[0].0, ab[0].1, ab[1].0, ab[1].1, ab[2].0, ab[2].1
);
let result = solve(n, &ab);
println!("{}", result);
eprintln!("time: {}ms", tins.elapsed().as_millis());
}
trait Change {
fn chmax(&mut self, x: Self);
fn chmin(&mut self, x: Self);
}
impl<T: PartialOrd> Change for T {
fn chmax(&mut self, x: T) {
if *self < x {
*self = x;
}
}
fn chmin(&mut self, x: T) {
if *self > x {
*self = x;
}
}
}