Submission #3750820


Source Code Expand

use std::collections::BTreeSet;

const INF: usize = 1e15 as usize;

fn main() {
    let s = std::io::stdin();
    let mut sc = Scanner { reader: s.lock() };
    let n: usize = sc.read();
    let l: usize = sc.read();

    let mut trie = Trie::new();
    for _ in 0..n {
        let s = sc.chars();
        trie.add(&s, 0);
    }
    let mut count = vec![];
    trie.count_tree(0, &mut count);

    let mut ans = 0;
    for grundy in count.iter().map(|&depth| (l - depth).trailing_zeros() + 1) {
        ans ^= grundy;
    }
    println!("{}", if ans == 0 { "Bob" } else { "Alice" });

    // let mut grundy = vec![INF; 31];
    // grundy[0] = 0;
    // get(30, &mut grundy);
    // println!("{:?}", grundy);
}

struct Trie {
    child: Vec<Option<Trie>>,
}

impl Trie {
    fn new() -> Self {
        Trie {
            child: vec![None, None],
        }
    }

    fn count_tree(&self, depth: usize, result: &mut Vec<usize>) {
        let len = self.child.iter().filter(|c| c.is_some()).count();
        if len == 1 {
            result.push(depth);
        }
        for child in self.child.iter() {
            match child {
                Some(child) => child.count_tree(depth + 1, result),
                None => {}
            }
        }
    }

    fn add(&mut self, s: &Vec<char>, pos: usize) {
        if s.len() == pos {
            return;
        }
        let index = s[pos] as usize - ('0' as usize);
        self.child[index].get_or_insert(Trie::new()).add(s, pos + 1);
    }
}

fn get(i: usize, grundy: &mut Vec<usize>) -> usize {
    if grundy[i] != INF {
        return grundy[i];
    }

    let mut set = BTreeSet::new();
    for k in 1..(i + 1) {
        let mut g = 0;
        for j in k..i {
            g ^= get(j, grundy);
        }
        set.insert(g);
    }
    for j in 0.. {
        if !set.contains(&j) {
            grundy[i] = j;
            break;
        }
    }
    grundy[i]
}

pub struct Scanner<R> {
    reader: R,
}

impl<R: std::io::Read> Scanner<R> {
    pub fn read<T: std::str::FromStr>(&mut self) -> T {
        use std::io::Read;
        let buf = self
            .reader
            .by_ref()
            .bytes()
            .map(|b| b.unwrap())
            .skip_while(|&b| b == b' ' || b == b'\n')
            .take_while(|&b| b != b' ' && b != b'\n')
            .collect::<Vec<_>>();
        unsafe { std::str::from_utf8_unchecked(&buf) }
            .parse()
            .ok()
            .expect("Parse error.")
    }
    pub fn read_vec<T: std::str::FromStr>(&mut self, n: usize) -> Vec<T> {
        (0..n).map(|_| self.read()).collect()
    }
    pub fn chars(&mut self) -> Vec<char> {
        self.read::<String>().chars().collect()
    }
}

Submission Info

Submission Time
Task E - Prefix-free Game
User kenkoooo
Language Rust (1.15.1)
Score 0
Code Size 2813 Byte
Status CE

Compile Error

error[E0308]: mismatched types
  --> ./Main.rs:49:17
   |
49 |                 Some(child) => child.count_tree(depth + 1, result),
   |                 ^^^^^^^^^^^ expected reference, found enum `std::option::Option`
   |
   = note: expected type `&std::option::Option<Trie>`
   = note:    found type `std::option::Option<_>`

error[E0308]: mismatched types
  --> ./Main.rs:50:17
   |
50 |                 None => {}
   |                 ^^^^ expected reference, found enum `std::option::Option`
   |
   = note: expected type `&std::option::Option<Trie>`
   = note:    found type `std::option::Option<_>`

error: no method named `get_or_insert` found for type `std::option::Option<Trie>` in the current scope
  --> ./Main.rs:60:27
   |
60 |         self.child[index].get_or_insert(Trie::new()).add(s, pos + 1);
   |                           ^^^^^^^^^^^^^

error: aborting due to 3 previous errors