結果

問題 No.2390 Udon Coupon (Hard)
ユーザー 👑 MizarMizar
提出日時 2023-06-30 00:24:38
言語 Rust
(1.77.0)
結果
AC  
実行時間 39 ms / 2,000 ms
コード長 2,741 bytes
コンパイル時間 629 ms
コンパイル使用メモリ 151,296 KB
実行使用メモリ 5,376 KB
最終ジャッジ日時 2024-04-15 20:46:32
合計ジャッジ時間 2,316 ms
ジャッジサーバーID
(参考情報)
judge2 / judge5
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 1 ms
5,248 KB
testcase_01 AC 1 ms
5,376 KB
testcase_02 AC 1 ms
5,376 KB
testcase_03 AC 1 ms
5,376 KB
testcase_04 AC 1 ms
5,376 KB
testcase_05 AC 3 ms
5,376 KB
testcase_06 AC 1 ms
5,376 KB
testcase_07 AC 0 ms
5,376 KB
testcase_08 AC 1 ms
5,376 KB
testcase_09 AC 29 ms
5,376 KB
testcase_10 AC 1 ms
5,376 KB
testcase_11 AC 1 ms
5,376 KB
testcase_12 AC 1 ms
5,376 KB
testcase_13 AC 1 ms
5,376 KB
testcase_14 AC 1 ms
5,376 KB
testcase_15 AC 1 ms
5,376 KB
testcase_16 AC 1 ms
5,376 KB
testcase_17 AC 1 ms
5,376 KB
testcase_18 AC 1 ms
5,376 KB
testcase_19 AC 1 ms
5,376 KB
testcase_20 AC 1 ms
5,376 KB
testcase_21 AC 1 ms
5,376 KB
testcase_22 AC 1 ms
5,376 KB
testcase_23 AC 1 ms
5,376 KB
testcase_24 AC 8 ms
5,376 KB
testcase_25 AC 9 ms
5,376 KB
testcase_26 AC 9 ms
5,376 KB
testcase_27 AC 9 ms
5,376 KB
testcase_28 AC 8 ms
5,376 KB
testcase_29 AC 21 ms
5,376 KB
testcase_30 AC 18 ms
5,376 KB
testcase_31 AC 21 ms
5,376 KB
testcase_32 AC 21 ms
5,376 KB
testcase_33 AC 20 ms
5,376 KB
testcase_34 AC 39 ms
5,376 KB
testcase_35 AC 37 ms
5,376 KB
testcase_36 AC 33 ms
5,376 KB
testcase_37 AC 37 ms
5,376 KB
testcase_38 AC 37 ms
5,376 KB
testcase_39 AC 11 ms
5,376 KB
testcase_40 AC 7 ms
5,376 KB
testcase_41 AC 11 ms
5,376 KB
testcase_42 AC 8 ms
5,376 KB
testcase_43 AC 11 ms
5,376 KB
testcase_44 AC 8 ms
5,376 KB
testcase_45 AC 7 ms
5,376 KB
testcase_46 AC 4 ms
5,376 KB
testcase_47 AC 6 ms
5,376 KB
testcase_48 AC 10 ms
5,376 KB
testcase_49 AC 1 ms
5,376 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

// 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;
        }
    }
}
0