Submission #65960624


Source Code Expand

use proconio::input;

pub trait ChangeMinMax {
    fn change_min(&mut self, v: Self) -> bool;
    fn change_max(&mut self, v: Self) -> bool;
}

impl<T: PartialOrd> ChangeMinMax for T {
    fn change_min(&mut self, v: T) -> bool {
        *self > v && {
            *self = v;
            true
        }
    }

    fn change_max(&mut self, v: T) -> bool {
        *self < v && {
            *self = v;
            true
        }
    }
}

fn main() {
    let input = Input::read_input();
    let since = std::time::Instant::now();
    let state = annealing1::greedy(&input);
    let state = annealing2::State::new(state.C, state.A);
    println!("{}", state);

    let elapsed = (std::time::Instant::now() - since).as_secs_f64();
    let duration = 1.98 - elapsed;

    let state1 = annealing2::annealing(&input, state.clone(), duration * 0.5, 5e1, 1e0);
    let state2 = annealing2::annealing(&input, state, duration * 0.5, 5e1, 1e0);

    let state = if state1.evaluate_approx(&input) > state2.evaluate_approx(&input) {
        state1
    } else {
        state2
    };

    println!("{}", state);
}

/// 入力データ
#[derive(Clone)]
pub struct Input {
    pub S: Vec<Vec<usize>>,
    pub P: Vec<i64>,
}

impl Input {
    const N: usize = 36;
    const M: usize = 12;
    const L: usize = 1000000;

    fn read_input() -> Self {
        input! {
            _N: usize,
            _M: usize,
            _L: usize,
        }

        let mut S = vec![];
        let mut P = vec![];

        for _ in 0..Self::N {
            input! {
                s: String,
                p: i64,
            }

            S.push(s);
            P.push(p);
        }

        let S = S
            .into_iter()
            .map(|s| s.chars().map(|c| c as usize - 'a' as usize).collect())
            .collect();

        Self { S, P }
    }
}

mod annealing1 {
    use std::{cmp::Reverse, collections::BTreeSet};

    use crate::{annealing2, ChangeMinMax as _, Input};
    use itertools::Itertools;
    use ordered_float::OrderedFloat;
    use rand::Rng;

    pub fn greedy(input: &Input) -> State {
        let mut env = Env::new(input.clone(), 0.6);
        let mut matrix = vec![vec![0; Input::N]; Input::N];

        for i in 0..Input::N {
            let mut set = BTreeSet::new();

            for j in 0..input.S[i].len() - 1 {
                set.insert((input.S[i][j], input.S[i][j + 1]));
            }

            for &(u, v) in set.iter() {
                matrix[u][v] += input.P[i] * input.P[i];
            }
        }

        let C = vec![0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5];
        let mut A = vec![vec![0; Input::M]; Input::M];

        for i in 0..Input::M {
            let c = C[i];
            let mut B = vec![0; Input::M];

            for j in 0..Input::M {
                let c2 = C[j];
                B[j] += matrix[c][c2];
            }

            let sum = B.iter().sum::<i64>();
            let B_std = B
                .iter()
                .map(|&x| x as f64 * 100.0 / sum as f64)
                .collect::<Vec<_>>();
            let mut added = 0;
            let mut retain = vec![];

            for j in 0..Input::M {
                let v = B_std[j] as i32;
                A[i][j] = v;
                retain.push((v as f64 - A[i][j] as f64, j));
                added += v;
            }

            retain.sort_by_key(|(x, _)| Reverse(OrderedFloat(*x)));

            for j in 0..Input::M {
                if added >= 100 {
                    break;
                }

                A[i][retain[j].1] += 1;
                added += 1;
            }
        }

        let mut state = State::new(C, A);

        let mut word_indices = (0..Input::N).collect_vec();
        word_indices.sort_by_key(|&i| Reverse(env.input.P[i]));
        const WORD_CNT: usize = 15;

        for &i in word_indices.iter().take(WORD_CNT) {
            eprintln!("target: {}", env.input.P[i]);
        }

        for (i, &word_i) in word_indices.iter().enumerate().take(WORD_CNT) {
            env.word_indices.push((word_i, env.threshold, 0.1));
            let new_state = annealing(&env, state.clone(), 0.1, 1e-1, 1e-3);
            let score = new_state.evaluate_approx(&env);

            let P_mat = state.build_probability_matrix();
            let pi = State::compute_stationary(&P_mat, 10); // 10ステップ繰り返す
            let mut ok = true;

            for &(j, threshold, mul) in env.word_indices.iter() {
                ok &= mul != 1.0 || state.evaluate_approx_single(&env, &pi, j) - threshold >= 0.0;
            }

            if !ok {
                eprintln!("NG: {}", env.input.P[word_i]);
                env.word_indices.pop();
                continue;
            }

            state = new_state;
            println!(
                "{}",
                annealing2::State::new(state.C.clone(), state.A.clone())
            );

            if score >= 0.0 {
                env.word_indices.last_mut().unwrap().2 = 1.0;
                eprintln!("OK: {}", env.input.P[word_i]);
            } else {
                let prob_ln = state.evaluate_approx_single(&env, &pi, word_i);
                env.word_indices.last_mut().unwrap().1 = prob_ln;
                eprintln!("NG: {}", env.input.P[word_i]);
            }
        }

        state
    }

    pub struct Env {
        input: Input,
        // (index, threshold, mul)
        word_indices: Vec<(usize, f64, f64)>,
        ln: Vec<f64>,
        threshold: f64,
    }

    impl Env {
        const MIN_PROB: f64 = 1e-10;

        pub fn new(input: Input, target_expected_val: f64) -> Self {
            let word_indices = vec![];
            let mut ln = vec![Self::MIN_PROB.ln()];

            for i in 1..=100 {
                ln.push((i as f64).ln());
            }

            let threshold = target_expected_val.ln() - (Input::L as f64).ln();
            eprintln!("threshold: {}", threshold);

            Self {
                input,
                word_indices,
                ln,
                threshold,
            }
        }
    }

    /// 解の型:文字割り当てと遷移確率行列
    #[derive(Clone)]
    pub struct State {
        pub C: Vec<usize>,    // 長さ M の文字割り当て ('a'~'f')
        pub A: Vec<Vec<i32>>, // M×M の遷移確率行列(各行の和=100)
    }

    impl State {
        pub fn new(C: Vec<usize>, A: Vec<Vec<i32>>) -> Self {
            Self { C, A }
        }

        /// 遷移確率行列 P: A[i][j]/100.0 の f64 行列に変換
        pub fn build_probability_matrix(&self) -> [[f64; Input::M]; Input::M] {
            let mut P = [[0.0; Input::M]; Input::M];

            for i in 0..Input::M {
                for j in 0..Input::M {
                    P[i][j] = (self.A[i][j] as f64) / 100.0;
                }
            }

            P
        }

        /// べき乗法で定常分布 π を求める
        pub fn compute_stationary(
            P: &[[f64; Input::M]; Input::M],
            iters: usize,
        ) -> [f64; Input::M] {
            let mut pi = [1.0 / Input::M as f64; Input::M];

            for _ in 0..iters {
                let mut next = [0.0; Input::M];

                for (pi, p) in pi.iter().zip(P.iter()) {
                    for (next, p) in next.iter_mut().zip(p.iter()) {
                        *next += pi * p;
                    }
                }

                pi = next;
            }

            pi
        }

        pub fn evaluate_approx(&self, env: &Env) -> f64 {
            let P_mat = self.build_probability_matrix();
            let pi = Self::compute_stationary(&P_mat, 10); // 10ステップ繰り返す

            let mut total = 0.0;

            for &(word_i, threshold, mul) in env.word_indices.iter() {
                let prob_ln = self.evaluate_approx_single(env, &pi, word_i);
                total += (prob_ln - threshold).min(0.0) * mul;
            }

            total
        }

        fn evaluate_approx_single(&self, env: &Env, pi: &[f64], word_i: usize) -> f64 {
            let word_idxs = &env.input.S[word_i];
            let mut prob = [pi[word_idxs[0] * 2], pi[word_idxs[0] * 2 + 1]];
            let mut prev_c = word_idxs[0];

            for &c in &word_idxs[1..] {
                let mut next_prob = [0.0; 2];

                for i in 0..2 {
                    for j in 0..2 {
                        next_prob[j] += prob[i] * self.A[prev_c * 2 + i][c * 2 + j] as f64 / 100.0;
                    }
                }

                prob = next_prob;
                prev_c = c;
            }

            let prob = prob[0] + prob[1];
            let prob_ln = prob.max(1e-30).ln();
            prob_ln
        }

        pub fn neigh1(mut self, rng: &mut impl Rng) -> Self {
            let i = rng.gen_range(0..Input::M);
            let from = loop {
                let j = rng.gen_range(0..Input::M);

                if self.A[i][j] > 0 {
                    break j;
                }
            };

            let to = loop {
                let j = rng.gen_range(0..Input::M);

                if j != from {
                    break j;
                }
            };

            self.A[i][from] -= 1;
            self.A[i][to] += 1;
            self
        }

        pub fn neigh2(mut self, rng: &mut impl Rng) -> Self {
            let (i, j, k, l) = loop {
                let mut cands = (0..Input::M).collect_vec();
                let index = rng.gen_range(0..cands.len());
                let i = cands.swap_remove(index);
                let index = rng.gen_range(0..cands.len());
                let j = cands.swap_remove(index);

                let mut cands = (0..Input::M).collect_vec();
                let index = rng.gen_range(0..cands.len());
                let k = cands.swap_remove(index);
                let index = rng.gen_range(0..cands.len());
                let l = cands.swap_remove(index);

                if self.A[i][k] > 0 && self.A[j][l] > 0 {
                    break (i, j, k, l);
                }
            };

            self.A[i][k] -= 1;
            self.A[j][k] += 1;
            self.A[i][l] += 1;
            self.A[j][l] -= 1;
            self
        }
    }

    /// 焼きなまし本体
    pub fn annealing(
        env: &Env,
        initial_solution: State,
        duration: f64,
        temp0: f64,
        temp1: f64,
    ) -> State {
        let mut solution = initial_solution;
        let mut best_solution = solution.clone();
        let mut current_score = solution.evaluate_approx(env);
        let mut best_score = current_score;
        let init_score = current_score;

        let mut all_iter = 0;
        let mut valid_iter = 0;
        let mut accepted_count = 0;
        let mut update_count = 0;
        let mut rng = rand_pcg::Pcg64Mcg::new(42);

        let duration_inv = 1.0 / duration;
        let since = std::time::Instant::now();

        let mut inv_temp = 1.0 / temp0;

        loop {
            if current_score >= 0.0 {
                break;
            }

            all_iter += 1;
            if (all_iter & ((1 << 4) - 1)) == 0 {
                let time = (std::time::Instant::now() - since).as_secs_f64() * duration_inv;
                let temp = f64::powf(temp0, 1.0 - time) * f64::powf(temp1, time);
                inv_temp = 1.0 / temp;

                if time >= 1.0 {
                    break;
                }
            }

            // 変形
            let new_solution = if rng.gen_bool(0.5) {
                solution.clone().neigh1(&mut rng)
            } else {
                solution.clone().neigh2(&mut rng)
            };

            // スコア計算
            let new_score = new_solution.evaluate_approx(env);
            let score_diff = new_score - current_score;

            if score_diff >= 0.0 || rng.gen_bool(f64::exp(score_diff as f64 * inv_temp)) {
                // 解の更新
                current_score = new_score;
                accepted_count += 1;
                solution = new_solution;

                if best_score.change_max(current_score) {
                    best_solution = solution.clone();
                    update_count += 1;
                }
            }

            valid_iter += 1;
        }

        eprintln!("===== annealing =====");
        eprintln!("init score : {}", init_score);
        eprintln!("score      : {}", best_score);
        eprintln!("all iter   : {}", all_iter);
        eprintln!("valid iter : {}", valid_iter);
        eprintln!("accepted   : {}", accepted_count);
        eprintln!("updated    : {}", update_count);
        eprintln!("");

        best_solution
    }
}

mod annealing2 {
    use std::fmt::Display;

    use itertools::Itertools;
    use rand::Rng;

    use crate::{ChangeMinMax as _, Input};

    /// 解の型:文字割り当てと遷移確率行列
    #[derive(Clone)]
    pub struct State {
        pub C: Vec<usize>,    // 長さ M の文字割り当て ('a'~'f')
        pub A: Vec<Vec<i32>>, // M×M の遷移確率行列(各行の和=100)
    }

    impl State {
        pub fn new(C: Vec<usize>, A: Vec<Vec<i32>>) -> Self {
            Self { C, A }
        }

        /// 遷移確率行列 P: A[i][j]/100.0 の f64 行列に変換
        pub fn build_probability_matrix(&self) -> [[f64; Input::M]; Input::M] {
            let mut P = [[0.0; Input::M]; Input::M];

            for i in 0..Input::M {
                for j in 0..Input::M {
                    P[i][j] = (self.A[i][j] as f64) / 100.0;
                }
            }

            P
        }

        /// べき乗法で定常分布 π を求める
        pub fn compute_stationary(
            P: &[[f64; Input::M]; Input::M],
            iters: usize,
        ) -> [f64; Input::M] {
            let mut pi = [1.0 / Input::M as f64; Input::M];

            for _ in 0..iters {
                let mut next = [0.0; Input::M];

                for (pi, p) in pi.iter().zip(P.iter()) {
                    for (next, p) in next.iter_mut().zip(p.iter()) {
                        *next += pi * p;
                    }
                }

                pi = next;
            }

            pi
        }

        pub fn evaluate_approx(&self, input: &Input) -> f64 {
            let P_mat = self.build_probability_matrix();
            let pi = Self::compute_stationary(&P_mat, 10); // 10ステップ繰り返す

            let mut total = 0.0;
            let L = Input::L as f64;
            for (word_idxs, &weight) in input.S.iter().zip(&input.P) {
                let mut prob = [pi[word_idxs[0] * 2], pi[word_idxs[0] * 2 + 1]];
                let mut prev_c = word_idxs[0];

                for &c in &word_idxs[1..] {
                    let mut next_prob = [0.0; 2];

                    for i in 0..2 {
                        for j in 0..2 {
                            next_prob[j] +=
                                prob[i] * self.A[prev_c * 2 + i][c * 2 + j] as f64 / 100.0;
                        }
                    }

                    prob = next_prob;
                    prev_c = c;
                }

                let prob = prob[0] + prob[1];
                let q = 1.0 - (1.0 - prob).powi(Input::L as i32);

                total += q * weight as f64;
            }

            total
        }

        pub fn neigh1(mut self, rng: &mut impl Rng) -> Self {
            let i = rng.gen_range(0..Input::M);
            let from = loop {
                let j = rng.gen_range(0..Input::M);

                if self.A[i][j] > 0 {
                    break j;
                }
            };

            let to = loop {
                let j = rng.gen_range(0..Input::M);

                if j != from {
                    break j;
                }
            };

            self.A[i][from] -= 1;
            self.A[i][to] += 1;
            self
        }

        pub fn neigh2(mut self, rng: &mut impl Rng) -> Self {
            let (i, j, k, l) = loop {
                let mut cands = (0..Input::M).collect_vec();
                let index = rng.gen_range(0..cands.len());
                let i = cands.swap_remove(index);
                let index = rng.gen_range(0..cands.len());
                let j = cands.swap_remove(index);

                let mut cands = (0..Input::M).collect_vec();
                let index = rng.gen_range(0..cands.len());
                let k = cands.swap_remove(index);
                let index = rng.gen_range(0..cands.len());
                let l = cands.swap_remove(index);

                if self.A[i][k] > 0 && self.A[j][l] > 0 {
                    break (i, j, k, l);
                }
            };

            self.A[i][k] -= 1;
            self.A[j][k] += 1;
            self.A[i][l] += 1;
            self.A[j][l] -= 1;
            self
        }
    }

    impl Display for State {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
            for i in 0..Input::M {
                write!(f, "{}", (self.C[i] as u8 + b'a') as char)?;

                for j in 0..Input::M {
                    write!(f, " {}", self.A[i][j])?;
                }

                writeln!(f)?;
            }

            Ok(())
        }
    }

    /// 焼きなまし本体
    pub fn annealing(
        input: &Input,
        initial_solution: State,
        duration: f64,
        temp0: f64,
        temp1: f64,
    ) -> State {
        let mut solution = initial_solution;
        let mut best_solution = solution.clone();
        let mut current_score = solution.evaluate_approx(input);
        let mut best_score = current_score;
        let init_score = current_score;

        let mut all_iter = 0;
        let mut valid_iter = 0;
        let mut accepted_count = 0;
        let mut update_count = 0;
        let mut rng = rand_pcg::Pcg64Mcg::new(42);

        let duration_inv = 1.0 / duration;
        let since = std::time::Instant::now();

        let mut inv_temp = 1.0 / temp0;

        loop {
            all_iter += 1;
            if (all_iter & ((1 << 4) - 1)) == 0 {
                let time = (std::time::Instant::now() - since).as_secs_f64() * duration_inv;
                let temp = f64::powf(temp0, 1.0 - time) * f64::powf(temp1, time);
                inv_temp = 1.0 / temp;

                if time >= 1.0 {
                    break;
                }
            }

            // 変形
            let new_solution = if rng.gen_bool(0.5) {
                solution.clone().neigh1(&mut rng)
            } else {
                solution.clone().neigh2(&mut rng)
            };

            // スコア計算
            let new_score = new_solution.evaluate_approx(input);
            let score_diff = new_score - current_score;

            if score_diff >= 0.0 || rng.gen_bool(f64::exp(score_diff as f64 * inv_temp)) {
                // 解の更新
                current_score = new_score;
                accepted_count += 1;
                solution = new_solution;

                if best_score.change_max(current_score) {
                    best_solution = solution.clone();
                    update_count += 1;
                }
            }

            valid_iter += 1;
        }

        eprintln!("===== annealing =====");
        eprintln!("init score : {}", init_score);
        eprintln!("score      : {}", best_score);
        eprintln!("all iter   : {}", all_iter);
        eprintln!("valid iter : {}", valid_iter);
        eprintln!("accepted   : {}", accepted_count);
        eprintln!("updated    : {}", update_count);
        eprintln!("");

        best_solution
    }
}

Submission Info

Submission Time
Task A - Lovely Language Model
User terry_u16
Language Rust (rustc 1.70.0)
Score 6922303
Code Size 20318 Byte
Status AC
Exec Time 1981 ms
Memory 2780 KiB

Compile Error

warning: unused variable: `i`
   --> src/main.rs:160:14
    |
160 |         for (i, &word_i) in word_indices.iter().enumerate().take(WORD_CNT) {
    |              ^ help: if this is intentional, prefix it with an underscore: `_i`
    |
    = note: `#[warn(unused_variables)]` on by default

warning: unused variable: `L`
   --> src/main.rs:503:17
    |
503 |             let L = Input::L as f64;
    |                 ^ help: if this is intentional, prefix it with an underscore: `_L`

warning: field `ln` is never read
   --> src/main.rs:202:9
    |
198 |     pub struct Env {
    |                --- field in this struct
...
202 |         ln: Vec<f64>,
    |         ^^
    |
    = note: `#[warn(dead_code)]` on by default

warning: structure field `S` should have a snake case name
  --> src/main.rs:49:9
   |
49 |     pub S: Vec<Vec<usize>>,
   |         ^ help: convert the identifier to snake case (notice the capitalization): `s`
   |
   = note: `#[warn(non_snake_case)]` on by default

warning: structure field `P` should have a snake case name
  --> src/main.rs:50:9
   |
50 |     pub P: Vec<i64>,
   |         ^ help: convert the identifier to snake case: `p`

warning: variable `_N` should have a snake case name
  --> src/main.rs:60:13
   |
60 |             _N: usize,
   |             ^^ help: convert the identifier to snake case: `_n`

warning: variable `_M` should have a snake case name
  --> src/main.rs:61:13
   |
61 |             _M: usize,
   |             ^^ help: convert the identifier to snake case: `_m`

warning: variable `_L` should have a snake case name
  --> src/main.rs:62:13
   |
62 |             _L: usize,
   |             ^^ help: convert the identifier to snake case: `_l`

warning: variable `S` should have a snake case name
  --> src/main.rs:65:17
   |
65 |         let mut S = vec![];
   |                 ^ help: convert the identifier to snake case (notice the capitalization): `s`

warning: variable `P` should have a snake case name
  --> src/main.rs:66:17
   |
66 |         let mut P = vec![];
   |                 ^ help: convert the identifier to snake case: `p`

warning: variable `S` should have a snake case name
  --> src/main.rs:78:13
   |
78 |         let S = S
   |             ^ help: convert the identifier to snake case (notice the capitalization): `s`

warning: variable `C` should have a snake case name
   --> src/main.rs:111:13
    |
111 |         let C = vec![0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5];
    |             ^ help: convert the identifier to snake case (notice the capitalization): `c`

warning: variable `A` should have a snake case name
   --> src/main.rs:112:17
    |
112 |         let mut A = vec![vec![0; Input::M]; Input::M];
    |                 ^ help: convert the identifier to snake case: `a`

warning: variable `B` should have a snake case name
   --> src/main.rs:116:21
    |
116 |             let mut B = vec![0; Input::M];
    |                     ^ help: convert the identifier to snake case: `b`

warning: variable `B_std` should have a snake case name
   --> src/main.rs:124:17
    |
124 |             let B_std = B
    |                 ^^^^^ help: convert the identifier to snake case: `b_std`

warning: variable `P_mat` should have a snake case name
   --> src/main.rs:165:17
    |
165 |             let P_mat = state.build_probability_matrix();
    |                 ^^^^^ help: convert the identifier to snake case: `p_mat`

warning: structure field `C` should have a snake case name
   --> src/main.rs:232:13
    |
232 |         pub C: Vec<usize>,    // 長さ M の文字割り当て ('a'~'f')
    |             ^ help: convert the identifier to snake case (notice the capitalization): `c`

warning: structure field `A` should have a snake case name
   --> src/main.rs:233:13
    |
233 |         pub A: Vec<Vec<i32>>, // M×M の遷移確率行列(各行の和=100)
    |             ^ help: convert the identifier to snake case: `a`

warning: variable `C` should have a snake case name
   --> src/main.rs:237:20
    |
237 |         pub fn new(C: Vec<usize>, A: Vec<Vec<i32>>) -> Self {
    |                    ^ help: convert the identifier to snake case (notice the capitalization): `c`

warning: variable `A` should have a snake case name
   --> src/main.rs:237:35
    |
237 |         pub fn new(C: Vec<usize>, A: Vec<Vec<i32>>) -> Self {
    |                                   ^ help: convert the identifier to snake case: `a`

warning: variable `P` should have a snake case name
   --> src/main.rs:243:21
    |
243 |             let mut P = [[0.0; Input::M]; Input::M];
    |                     ^ help: convert the identifier to snake case: `p`

warning: variable `P` should have a snake case name
   --> src/main.rs:256:13
    |
256 |             P: &[[f64; Input::M]; Input::M],
    |             ^ help: convert the identifier to snake case: `p`

warning: variable `P_mat` should have a snake case name
   --> src/main.rs:277:17
    |
277 |             let P_mat = self.build_probability_matrix();
    |                 ^^^^^ help: convert the identifier to snake case: `p_mat`

warning: structure field `C` should have a snake case name
   --> src/main.rs:454:13
    |
454 |         pub C: Vec<usize>,    // 長さ M の文字割り当て ('a'~'f')
    |             ^ help: convert the identifier to snake case (notice the capitalization): `c`

warning: structure field `A` should have a snake case name
   --> src/main.rs:455:13
    |
455 |         pub A: Vec<Vec<i32>>, // M×M の遷移確率行列(各行の和=100)
    |             ^ help: convert the identifier to snake case: `a`

warning: variable `C` should have a snake case name
   --> src/main.rs:459:20
    |
459 |         pub fn new(C: Vec<usize>, A: Vec<Vec<i32>>) -> Self {
    |                    ^ help: convert the identifier to snake case (notice the capitalization): `c`

warning: variable `A` should have a snake case name
   --> src/main.rs:459:35
    |
459 |         pub fn new(C: Vec<usize>, A: Vec<Vec<i32>>) -> Self {
    |                                   ^ help: convert the identifier to snake case: `a`

warning: variable `P` should have a snake case name
   --> src/main.rs:465:21
    |
465 |             let mut P = [[0.0; Input::M]; Input::M];
    |                     ^ help: convert the identifier to snake case: `p`

warning: variable `P` should have a snake case name
   --> src/main.rs:478:13
    |
478 |             P: &[[f64; Input::M]; Input::M],
    |             ^ help: convert the identifier to snake case: `p`

warning: variable `P_mat` should have a snake case name
   --> src/main.rs:499:17
    |
499 |             let P_mat = self.build_probability_matrix();
    |                 ^^^^^ help: convert the identifier to snake case: `p_mat`

warning: variable `L` should have a snake case name
   --> src/main.rs:503:17
    |
503 |             let L = Input::L as f64;
    |                 ^ help: convert the identifier to snake case: `l`

Judge Result

Set Name test_ALL
Score / Max Score 6922303 / 150000000
Status
AC × 150
Set Name Test Cases
test_ALL test_0000.txt, test_0001.txt, test_0002.txt, test_0003.txt, test_0004.txt, test_0005.txt, test_0006.txt, test_0007.txt, test_0008.txt, test_0009.txt, test_0010.txt, test_0011.txt, test_0012.txt, test_0013.txt, test_0014.txt, test_0015.txt, test_0016.txt, test_0017.txt, test_0018.txt, test_0019.txt, test_0020.txt, test_0021.txt, test_0022.txt, test_0023.txt, test_0024.txt, test_0025.txt, test_0026.txt, test_0027.txt, test_0028.txt, test_0029.txt, test_0030.txt, test_0031.txt, test_0032.txt, test_0033.txt, test_0034.txt, test_0035.txt, test_0036.txt, test_0037.txt, test_0038.txt, test_0039.txt, test_0040.txt, test_0041.txt, test_0042.txt, test_0043.txt, test_0044.txt, test_0045.txt, test_0046.txt, test_0047.txt, test_0048.txt, test_0049.txt, test_0050.txt, test_0051.txt, test_0052.txt, test_0053.txt, test_0054.txt, test_0055.txt, test_0056.txt, test_0057.txt, test_0058.txt, test_0059.txt, test_0060.txt, test_0061.txt, test_0062.txt, test_0063.txt, test_0064.txt, test_0065.txt, test_0066.txt, test_0067.txt, test_0068.txt, test_0069.txt, test_0070.txt, test_0071.txt, test_0072.txt, test_0073.txt, test_0074.txt, test_0075.txt, test_0076.txt, test_0077.txt, test_0078.txt, test_0079.txt, test_0080.txt, test_0081.txt, test_0082.txt, test_0083.txt, test_0084.txt, test_0085.txt, test_0086.txt, test_0087.txt, test_0088.txt, test_0089.txt, test_0090.txt, test_0091.txt, test_0092.txt, test_0093.txt, test_0094.txt, test_0095.txt, test_0096.txt, test_0097.txt, test_0098.txt, test_0099.txt, test_0100.txt, test_0101.txt, test_0102.txt, test_0103.txt, test_0104.txt, test_0105.txt, test_0106.txt, test_0107.txt, test_0108.txt, test_0109.txt, test_0110.txt, test_0111.txt, test_0112.txt, test_0113.txt, test_0114.txt, test_0115.txt, test_0116.txt, test_0117.txt, test_0118.txt, test_0119.txt, test_0120.txt, test_0121.txt, test_0122.txt, test_0123.txt, test_0124.txt, test_0125.txt, test_0126.txt, test_0127.txt, test_0128.txt, test_0129.txt, test_0130.txt, test_0131.txt, test_0132.txt, test_0133.txt, test_0134.txt, test_0135.txt, test_0136.txt, test_0137.txt, test_0138.txt, test_0139.txt, test_0140.txt, test_0141.txt, test_0142.txt, test_0143.txt, test_0144.txt, test_0145.txt, test_0146.txt, test_0147.txt, test_0148.txt, test_0149.txt
Case Name Status Exec Time Memory
test_0000.txt AC 1981 ms 2568 KiB
test_0001.txt AC 1981 ms 2644 KiB
test_0002.txt AC 1981 ms 2712 KiB
test_0003.txt AC 1981 ms 2712 KiB
test_0004.txt AC 1981 ms 2644 KiB
test_0005.txt AC 1981 ms 2692 KiB
test_0006.txt AC 1981 ms 2744 KiB
test_0007.txt AC 1981 ms 2620 KiB
test_0008.txt AC 1981 ms 2672 KiB
test_0009.txt AC 1981 ms 2680 KiB
test_0010.txt AC 1981 ms 2692 KiB
test_0011.txt AC 1981 ms 2608 KiB
test_0012.txt AC 1981 ms 2580 KiB
test_0013.txt AC 1981 ms 2648 KiB
test_0014.txt AC 1980 ms 2644 KiB
test_0015.txt AC 1981 ms 2772 KiB
test_0016.txt AC 1981 ms 2772 KiB
test_0017.txt AC 1981 ms 2780 KiB
test_0018.txt AC 1981 ms 2584 KiB
test_0019.txt AC 1981 ms 2568 KiB
test_0020.txt AC 1981 ms 2684 KiB
test_0021.txt AC 1981 ms 2760 KiB
test_0022.txt AC 1981 ms 2604 KiB
test_0023.txt AC 1981 ms 2620 KiB
test_0024.txt AC 1981 ms 2608 KiB
test_0025.txt AC 1981 ms 2768 KiB
test_0026.txt AC 1981 ms 2684 KiB
test_0027.txt AC 1981 ms 2688 KiB
test_0028.txt AC 1981 ms 2708 KiB
test_0029.txt AC 1981 ms 2756 KiB
test_0030.txt AC 1981 ms 2608 KiB
test_0031.txt AC 1981 ms 2692 KiB
test_0032.txt AC 1981 ms 2624 KiB
test_0033.txt AC 1981 ms 2688 KiB
test_0034.txt AC 1981 ms 2612 KiB
test_0035.txt AC 1981 ms 2684 KiB
test_0036.txt AC 1981 ms 2776 KiB
test_0037.txt AC 1981 ms 2780 KiB
test_0038.txt AC 1981 ms 2768 KiB
test_0039.txt AC 1981 ms 2604 KiB
test_0040.txt AC 1981 ms 2692 KiB
test_0041.txt AC 1981 ms 2740 KiB
test_0042.txt AC 1981 ms 2700 KiB
test_0043.txt AC 1981 ms 2700 KiB
test_0044.txt AC 1981 ms 2776 KiB
test_0045.txt AC 1981 ms 2772 KiB
test_0046.txt AC 1981 ms 2764 KiB
test_0047.txt AC 1981 ms 2608 KiB
test_0048.txt AC 1981 ms 2616 KiB
test_0049.txt AC 1981 ms 2768 KiB
test_0050.txt AC 1981 ms 2616 KiB
test_0051.txt AC 1981 ms 2676 KiB
test_0052.txt AC 1981 ms 2584 KiB
test_0053.txt AC 1981 ms 2608 KiB
test_0054.txt AC 1981 ms 2700 KiB
test_0055.txt AC 1981 ms 2692 KiB
test_0056.txt AC 1981 ms 2668 KiB
test_0057.txt AC 1981 ms 2700 KiB
test_0058.txt AC 1981 ms 2712 KiB
test_0059.txt AC 1981 ms 2692 KiB
test_0060.txt AC 1981 ms 2768 KiB
test_0061.txt AC 1981 ms 2700 KiB
test_0062.txt AC 1981 ms 2628 KiB
test_0063.txt AC 1981 ms 2756 KiB
test_0064.txt AC 1981 ms 2708 KiB
test_0065.txt AC 1981 ms 2612 KiB
test_0066.txt AC 1981 ms 2684 KiB
test_0067.txt AC 1981 ms 2584 KiB
test_0068.txt AC 1981 ms 2760 KiB
test_0069.txt AC 1981 ms 2608 KiB
test_0070.txt AC 1981 ms 2504 KiB
test_0071.txt AC 1981 ms 2620 KiB
test_0072.txt AC 1981 ms 2604 KiB
test_0073.txt AC 1981 ms 2612 KiB
test_0074.txt AC 1981 ms 2752 KiB
test_0075.txt AC 1981 ms 2692 KiB
test_0076.txt AC 1981 ms 2612 KiB
test_0077.txt AC 1981 ms 2668 KiB
test_0078.txt AC 1981 ms 2676 KiB
test_0079.txt AC 1981 ms 2676 KiB
test_0080.txt AC 1981 ms 2712 KiB
test_0081.txt AC 1981 ms 2760 KiB
test_0082.txt AC 1981 ms 2644 KiB
test_0083.txt AC 1981 ms 2612 KiB
test_0084.txt AC 1981 ms 2608 KiB
test_0085.txt AC 1981 ms 2584 KiB
test_0086.txt AC 1981 ms 2696 KiB
test_0087.txt AC 1981 ms 2764 KiB
test_0088.txt AC 1981 ms 2588 KiB
test_0089.txt AC 1981 ms 2624 KiB
test_0090.txt AC 1981 ms 2764 KiB
test_0091.txt AC 1981 ms 2684 KiB
test_0092.txt AC 1981 ms 2688 KiB
test_0093.txt AC 1981 ms 2696 KiB
test_0094.txt AC 1981 ms 2608 KiB
test_0095.txt AC 1981 ms 2548 KiB
test_0096.txt AC 1981 ms 2756 KiB
test_0097.txt AC 1981 ms 2672 KiB
test_0098.txt AC 1981 ms 2612 KiB
test_0099.txt AC 1981 ms 2516 KiB
test_0100.txt AC 1981 ms 2760 KiB
test_0101.txt AC 1981 ms 2760 KiB
test_0102.txt AC 1981 ms 2700 KiB
test_0103.txt AC 1981 ms 2676 KiB
test_0104.txt AC 1981 ms 2772 KiB
test_0105.txt AC 1981 ms 2612 KiB
test_0106.txt AC 1981 ms 2612 KiB
test_0107.txt AC 1981 ms 2680 KiB
test_0108.txt AC 1981 ms 2688 KiB
test_0109.txt AC 1981 ms 2680 KiB
test_0110.txt AC 1981 ms 2640 KiB
test_0111.txt AC 1981 ms 2708 KiB
test_0112.txt AC 1981 ms 2768 KiB
test_0113.txt AC 1981 ms 2668 KiB
test_0114.txt AC 1981 ms 2592 KiB
test_0115.txt AC 1981 ms 2608 KiB
test_0116.txt AC 1981 ms 2640 KiB
test_0117.txt AC 1981 ms 2760 KiB
test_0118.txt AC 1981 ms 2680 KiB
test_0119.txt AC 1981 ms 2688 KiB
test_0120.txt AC 1981 ms 2684 KiB
test_0121.txt AC 1981 ms 2612 KiB
test_0122.txt AC 1981 ms 2584 KiB
test_0123.txt AC 1981 ms 2504 KiB
test_0124.txt AC 1981 ms 2580 KiB
test_0125.txt AC 1981 ms 2684 KiB
test_0126.txt AC 1981 ms 2772 KiB
test_0127.txt AC 1981 ms 2748 KiB
test_0128.txt AC 1981 ms 2708 KiB
test_0129.txt AC 1981 ms 2776 KiB
test_0130.txt AC 1981 ms 2768 KiB
test_0131.txt AC 1981 ms 2684 KiB
test_0132.txt AC 1981 ms 2644 KiB
test_0133.txt AC 1981 ms 2760 KiB
test_0134.txt AC 1981 ms 2760 KiB
test_0135.txt AC 1981 ms 2688 KiB
test_0136.txt AC 1981 ms 2760 KiB
test_0137.txt AC 1981 ms 2640 KiB
test_0138.txt AC 1981 ms 2760 KiB
test_0139.txt AC 1981 ms 2608 KiB
test_0140.txt AC 1981 ms 2672 KiB
test_0141.txt AC 1981 ms 2756 KiB
test_0142.txt AC 1981 ms 2684 KiB
test_0143.txt AC 1981 ms 2532 KiB
test_0144.txt AC 1981 ms 2504 KiB
test_0145.txt AC 1981 ms 2604 KiB
test_0146.txt AC 1981 ms 2764 KiB
test_0147.txt AC 1981 ms 2768 KiB
test_0148.txt AC 1981 ms 2748 KiB
test_0149.txt AC 1981 ms 2704 KiB