Rust for Algorithmic Problem-Solving

Competitive Programming Templates

A competitive programming template combines a fast zero-allocation token scanner, an 8 KiB buffered output writer, modular arithmetic helpers, and multi-testcase orchestration into a single self-contained .rs file that compiles with zero external dependencies on any online judge (Codeforces, AtCoder, LeetCode, Kattis, CSES).

Anatomy of a Single-File Rust Algorithmic Template:
  1. `Scanner<'a>` over `io::read_to_string(io::stdin())`
     - `.next::<T>()`, `.next_bytes()`, `.next_vec::<T>(n)`
  2. `BufWriter<StdoutLock<'static>>`
     - Batches all `writeln!(out, ...)` calls into minimal OS syscalls
  3. `solve(&mut scan, &mut out)`
     - Invoked once (or inside `for _ in 0..t` for multi-testcase problems)

Complete Production-Ready Competitive Programming Template

use std::io::{self, BufWriter, Write};
use std::str::{FromStr, SplitAsciiWhitespace};

pub struct Scanner<'a> {
    it: SplitAsciiWhitespace<'a>,
}

impl<'a> Scanner<'a> {
    pub fn new(s: &'a str) -> Self {
        Self {
            it: s.split_ascii_whitespace(),
        }
    }

    #[inline]
    pub fn next<T: FromStr>(&mut self) -> T {
        self.it
            .next()
            .expect("EOF")
            .parse()
            .ok()
            .expect("parse error")
    }

    #[inline]
    pub fn next_str(&mut self) -> &'a str {
        self.it.next().expect("EOF")
    }

    #[inline]
    pub fn next_bytes(&mut self) -> &'a [u8] {
        self.next_str().as_bytes()
    }

    #[inline]
    pub fn next_vec<T: FromStr>(&mut self, n: usize) -> Vec<T> {
        (0..n).map(|_| self.next()).collect()
    }
}

/// Modular exponentiation: computes `(base^exp) % modulus` in O(log exp) time.
#[inline]
pub const fn mod_pow(mut base: u64, mut exp: u64, modulus: u64) -> u64 {
    let mut result = 1u64 % modulus;
    base %= modulus;
    while exp > 0 {
        if (exp & 1) == 1 {
            result = ((result as u128 * base as u128) % (modulus as u128)) as u64;
        }
        base = ((base as u128 * base as u128) % (modulus as u128)) as u64;
        exp >>= 1;
    }
    result
}

/// Greatest Common Divisor (Euclidean algorithm) in O(log(min(a, b))) time.
#[inline]
pub const fn gcd(mut a: u64, mut b: u64) -> u64 {
    while b != 0 {
        let r = a % b;
        a = b;
        b = r;
    }
    a
}

fn solve_test_case(scan: &mut Scanner<'_>, out: &mut impl Write) -> io::Result<()> {
    let n: usize = scan.next();
    let nums: Vec<u64> = scan.next_vec(n);

    let overall_gcd = nums.iter().copied().fold(0u64, gcd);
    let mod_ans = mod_pow(overall_gcd, 3, 1_000_000_007);
    writeln!(out, "{overall_gcd} {mod_ans}")
}

fn main() -> io::Result<()> {
    // In online judge submissions, read from stdin:
    // let input = io::read_to_string(io::stdin())?;
    let input = "2\n3\n12 18 24\n4\n10 25 35 50\n";

    let mut scan = Scanner::new(input);
    let stdout = io::stdout();
    let mut out = BufWriter::new(stdout.lock());

    let t: usize = scan.next();
    for _ in 0..t {
        solve_test_case(&mut scan, &mut out)?;
    }

    out.flush()
}
6 216
5 125

Quick Reference of Idiomatic Rust One-Liners for Contests

Task Idiomatic Rust Expression
Swap two elements in a slice slice.swap(i, j);
Update ans = min(ans, cand) ans = ans.min(cand); (or ans = ans.max(cand);)
Print space-separated Vec<i64> for (i, x) in v.iter().enumerate() { write!(out, "{x}{}", if i + 1 == v.len() { "\n" } else { " " })?; }
Safe (a * b) % MOD for 64-bit ints ((a as u128 * b as u128) % (MOD as u128)) as u64 (Zero 64-bit overflow risk!)
Ceiling integer division $\lceil a / b \rceil$ a.div_ceil(b) (Built into all unsigned integers in modern Rust!)
Absolute difference $|a - b|$ a.abs_diff(b) (Built into all integers; never overflows on signed i64::MIN!)