結果

問題 No.142 単なる配列の操作に関する実装問題
コンテスト
ユーザー cologne
提出日時 2026-01-18 19:57:43
言語 Rust
(1.92.0 + proconio + num + itertools)
結果
WA  
実行時間 -
コード長 4,411 bytes
記録
記録タグの例:
初AC ショートコード 純ショートコード 純主流ショートコード 最速実行時間
コンパイル時間 26,630 ms
コンパイル使用メモリ 411,588 KB
実行使用メモリ 7,848 KB
最終ジャッジ日時 2026-01-18 19:58:16
合計ジャッジ時間 29,747 ms
ジャッジサーバーID
(参考情報)
judge3 / judge6
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
other AC * 2 WA * 3
権限があれば一括ダウンロードができます

ソースコード

diff #
raw source code

use fio::*;

struct BitSet {
    n: usize,
    arr: Vec<u64>,
}

impl BitSet {
    fn new(n: usize) -> Self {
        BitSet {
            n,
            arr: vec![0; n.div_ceil(64) + 1], // to prevent off-by-1 error, and fill with 0.
        }
    }
    fn set(&mut self, idx: usize, val: bool) {
        assert!((0..self.n).contains(&idx));
        let (idx, rem) = (idx / 64, idx % 64);
        if val {
            self.arr[idx] |= 1u64 << rem;
        } else {
            self.arr[idx] &= !(1u64 << rem);
        }
    }
    fn get(&self, idx: usize) -> bool {
        assert!((0..self.n).contains(&idx));
        let (idx, rem) = (idx / 64, idx % 64);
        (self.arr[idx] & (1u64 << rem)) != 0
    }

    /// arr[s..t] ^= arr[u..v]
    fn rng_xor(&mut self, s: usize, t: usize, u: usize, v: usize) {
        assert!(s < t && t <= self.n && u < v && v <= self.n && t - s == v - u);
        let len = (v - u).div_ceil(64);
        if len == 0 {
            // no-op
            return;
        }
        let mut buf = vec![0u64; len + 1]; // to prevent off-by-1 error.
        // buf = arr[u..v]
        let rem = u % 64;
        if rem == 0 {
            for i in 0..len {
                buf[i] = self.arr[u / 64 + i];
            }
        } else {
            for i in 0..len {
                buf[i] = (self.arr[u / 64 + i] >> rem) | (self.arr[u / 64 + i + 1] << (64 - rem));
            }
        }
        // Ignore the last part if the last_block is not full.
        let last_block = (v-u) % 64;
        if last_block != 0 {
            buf[len - 1] &= (1u64 << last_block) - 1;
        }
        // arr[s..t] ^= buf
        let rem = s % 64;
        if rem == 0 {
            // the last part is filled with 0, so safe to XOR.
            for i in 0..len {
                self.arr[s / 64 + i] ^= buf[i];
            }
        } else {
            self.arr[s / 64] ^= buf[0] << rem;
            for i in 1..len {
                self.arr[s / 64 + i] ^= (buf[i - 1] >> (64 - rem)) | (buf[i] << rem);
            }
        }
    }
}

fn main() {
    let [n, s, x, y, z] = read_tuple::<usize, 5>();
    let mut bs = BitSet::new(n);
    let mut cur = s;
    bs.set(0, cur % 2 == 1);
    for i in 1..n {
        cur = (x * cur + y) % z;
        bs.set(i, cur % 2 == 1);
    }
    let q = read::<usize>();
    for _ in 0..q {
        let [s, t, u, v] = read_tuple::<usize, 4>();
        bs.rng_xor(u - 1, v, s - 1, t);
    }
    for i in 0..n {
        print!("{}", if bs.get(i) { 'O' } else { 'E' })
    }
}

mod fio {
    use std::{
        cell::RefCell,
        convert::TryInto,
        fmt::Debug,
        io::{BufRead, BufWriter, StdinLock, StdoutLock, stdin, stdout},
        str::FromStr,
    };
    thread_local! {
        pub static STDIN: RefCell<StdinLock<'static>> = RefCell::new(stdin().lock());
        pub static STDOUT: RefCell<BufWriter<StdoutLock<'static>>> = RefCell::new(BufWriter::new(stdout().lock()));
    }

    #[allow(dead_code)]
    pub fn read<T: FromStr>() -> T
    where
        <T as FromStr>::Err: Debug,
    {
        read_line().parse().unwrap()
    }

    #[allow(dead_code)]
    pub fn read_vec<T: FromStr>() -> Vec<T>
    where
        <T as FromStr>::Err: Debug,
    {
        read_line()
            .split_whitespace()
            .map(|x| x.parse().unwrap())
            .collect()
    }

    #[allow(dead_code)]
    pub fn read_tuple<T, const N: usize>() -> [T; N]
    where
        T: FromStr + Debug,
        <T as FromStr>::Err: Debug,
    {
        read_vec::<T>().try_into().unwrap()
    }

    /// whitespace at the end of the line is ignored
    pub fn read_line() -> String {
        let mut s = String::new();
        STDIN.with(|cell| {
            cell.borrow_mut().read_line(&mut s).unwrap();
        });
        String::from_str(s.trim_end()).unwrap()
    }
}

#[macro_export]
macro_rules! print {
    ($($t:tt)*) => {
        fio::STDOUT.with(|cell|{
            use std::io::Write;
            write!(cell.borrow_mut(), $($t)*).unwrap()
        })};
}

#[macro_export]
macro_rules! println {
    ($($t:tt)*) => {
        fio::STDOUT.with(|cell| {
            use std::io::Write;
            writeln!(cell.borrow_mut(), $($t)*).unwrap()
        })
    };
}

#[macro_export]
macro_rules! flush {
    () => {
        fio::STDOUT.with(|cell| {
            use std::io::Write;
            cell.borrow_mut().flush().unwrap()
        });
    };
}
0