E - Reverse 2^i 解説 by ngtkana


問題文にある操作をすべての \((a, b)\) に対して、\(b\) に関して昇順に、「改善するならばスワップ」と繰り返せばよいです。(結論、公式解説と同じ操作になります。)

コード

Rust 109 ms

use itertools::Itertools;
use proconio::input;

fn main() {
    input! {
        t: usize,
    }
    for _ in 0..t {
        input! {
            n: usize,
            mut p: [u32; 1 << n],
        }
        for b in 0..n {
            for a in (0..1 << n).filter(|&a| a & ((1 << (b + 1)) - 1) == 0) {
                if p[a] > p[a | 1 << b] {
                    for i in a..a | 1 << b {
                        p.swap(i, i | 1 << b);
                    }
                }
            }
        }
        println!("{}", p.iter().join(" "));
    }
}

別解法

Solalyth さんによると、\(b\) の大きい順に reverse していく方法でもできるみたいです。chunks_mut を使う実装アイデアも賢いですね。

https://x.com/alyth_sol/status/1941724831021670479

投稿日時:
最終更新: