結果

問題 No.2356 Back Door Tour in Four Seasons
ユーザー nautnaut
提出日時 2023-06-18 13:44:58
言語 Rust
(1.77.0)
結果
AC  
実行時間 1,261 ms / 2,000 ms
コード長 5,855 bytes
コンパイル時間 4,669 ms
コンパイル使用メモリ 160,444 KB
実行使用メモリ 44,404 KB
最終ジャッジ日時 2023-09-08 09:42:48
合計ジャッジ時間 42,375 ms
ジャッジサーバーID
(参考情報)
judge14 / judge12
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 965 ms
42,940 KB
testcase_01 AC 967 ms
43,392 KB
testcase_02 AC 970 ms
43,332 KB
testcase_03 AC 969 ms
42,988 KB
testcase_04 AC 1,112 ms
43,700 KB
testcase_05 AC 970 ms
43,904 KB
testcase_06 AC 970 ms
42,776 KB
testcase_07 AC 969 ms
43,304 KB
testcase_08 AC 1,124 ms
43,532 KB
testcase_09 AC 1,258 ms
42,896 KB
testcase_10 AC 1,258 ms
43,724 KB
testcase_11 AC 1,251 ms
43,576 KB
testcase_12 AC 1,257 ms
44,404 KB
testcase_13 AC 1,261 ms
44,104 KB
testcase_14 AC 1,259 ms
42,940 KB
testcase_15 AC 1,166 ms
42,912 KB
testcase_16 AC 1,241 ms
43,568 KB
testcase_17 AC 1,246 ms
42,688 KB
testcase_18 AC 1,242 ms
43,148 KB
testcase_19 AC 1,170 ms
44,080 KB
testcase_20 AC 1,249 ms
43,324 KB
testcase_21 AC 1,208 ms
42,996 KB
testcase_22 AC 1,172 ms
42,732 KB
testcase_23 AC 1,133 ms
43,200 KB
testcase_24 AC 1,250 ms
43,644 KB
testcase_25 AC 1,077 ms
43,180 KB
testcase_26 AC 1,210 ms
43,660 KB
testcase_27 AC 1,246 ms
43,824 KB
testcase_28 AC 959 ms
43,504 KB
testcase_29 AC 970 ms
43,424 KB
testcase_30 AC 1,060 ms
42,792 KB
testcase_31 AC 1,073 ms
42,780 KB
権限があれば一括ダウンロードができます
コンパイルメッセージ
warning: unused `Result` that must be used
  --> Main.rs:65:5
   |
65 |     writeln!(out, "{}", ans);
   |     ^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: this `Result` may be an `Err` variant, which should be handled
   = note: `#[warn(unused_must_use)]` on by default
   = note: this warning originates in the macro `writeln` (in Nightly builds, run with -Z macro-backtrace for more info)

warning: 1 warning emitted

ソースコード

diff #

#![allow(non_snake_case, unused_imports)]
use std::io::{self, prelude::*};
use std::str;

fn main() {
    let (stdin, stdout) = (io::stdin(), io::stdout());
    let mut scan = Scanner::new(stdin.lock());
    let mut out = io::BufWriter::new(stdout.lock());

    macro_rules! input {
        ($T: ty) => {
            scan.token::<$T>()
        };
    }

    let N = input!(usize);

    const MOD: usize = 998_244_353;

    let M = 100_001;
    let mut U = vec![0; M];
    let mut F = vec![0; M];
    let mut W = vec![0; M];
    let mut P = vec![0; M];
    let mut all_door = 0;

    for _ in 0..N {
        let S = input!(String);
        let A = input!(usize);

        all_door += A;

        if S == "U" {
            U[A] += MOD + ntt::pow_mod(N - 1, A) - ntt::pow_mod(N - 2, A);
            U[A] %= MOD;
        } else if S == "F" {
            F[A] += MOD + ntt::pow_mod(N - 1, A) - ntt::pow_mod(N - 2, A);
            F[A] %= MOD;
        } else if S == "W" {
            W[A] += MOD + ntt::pow_mod(N - 1, A) - ntt::pow_mod(N - 2, A);
            W[A] %= MOD;
        } else {
            P[A] += ntt::pow_mod(N - 1, A);
            P[A] %= MOD;
        }
    }

    let cnt = {
        let a = ntt::conv(U, F);
        let b = ntt::conv(a, W);
        let c = ntt::conv(b, P);
        c
    };

    let mut ans = 0;

    for (i, &c) in cnt.iter().enumerate() {
        if c > 0 {
            let other_pattern = ntt::pow_mod(N - 1, all_door - i);
            ans += c * other_pattern;
            ans %= MOD;
        }
    }

    writeln!(out, "{}", ans);
}

struct Scanner<R> {
    reader: R,
    buf_str: Vec<u8>,
    buf_iter: str::SplitWhitespace<'static>,
}
impl<R: BufRead> Scanner<R> {
    fn new(reader: R) -> Self {
        Self {
            reader,
            buf_str: vec![],
            buf_iter: "".split_whitespace(),
        }
    }
    fn token<T: str::FromStr>(&mut self) -> T {
        loop {
            if let Some(token) = self.buf_iter.next() {
                return token.parse().ok().expect("Failed parse");
            }
            self.buf_str.clear();
            self.reader
                .read_until(b'\n', &mut self.buf_str)
                .expect("Failed read");
            self.buf_iter = unsafe {
                let slice = str::from_utf8_unchecked(&self.buf_str);
                std::mem::transmute(slice.split_whitespace())
            }
        }
    }
}

pub mod ntt {
    const MOD: usize = 998_244_353;
    const ROOT: [usize; 24] = [
        1, 998244352, 911660635, 372528824, 929031873, 452798380, 922799308, 781712469, 476477967,
        166035806, 258648936, 584193783, 63912897, 350007156, 666702199, 968855178, 629671588,
        24514907, 996173970, 363395222, 565042129, 733596141, 267099868, 15311432,
    ];
    const ROOT_INV: [usize; 24] = [
        1, 998244352, 86583718, 509520358, 337190230, 87557064, 609441965, 135236158, 304459705,
        685443576, 381598368, 335559352, 129292727, 358024708, 814576206, 708402881, 283043518,
        3707709, 121392023, 704923114, 950391366, 428961804, 382752275, 469870224,
    ];

    pub fn pow_mod(x: usize, m: usize) -> usize {
        let mut ret = 1;
        let mut val = x;

        for i in 0..60 {
            if (m >> i) & 1 == 1 {
                ret *= val;
                ret %= MOD;
            }

            val *= val;
            val %= MOD;
        }

        ret
    }

    pub fn inv_mod(x: usize) -> usize {
        return pow_mod(x, MOD - 2);
    }

    pub fn ntt(mut f: Vec<usize>, depth: usize) -> Vec<usize> {
        let n = f.len();

        if n == 1 {
            return f;
        }

        let mut even = vec![0; n / 2];
        let mut odd = vec![0; n / 2];

        for i in 0..n / 2 {
            even[i] = f[2 * i];
            odd[i] = f[2 * i + 1];
        }

        even = ntt(even, depth - 1);
        odd = ntt(odd, depth - 1);

        let r = ROOT[depth];
        let mut now = 1;

        for i in 0..n / 2 {
            odd[i] *= now;
            odd[i] %= MOD;
            f[i] = (even[i] + odd[i]) % MOD;
            f[i + n / 2] = (MOD + even[i] - odd[i]) % MOD;

            now *= r;
            now %= MOD;
        }

        return f;
    }

    pub fn intt(mut f: Vec<usize>, depth: usize) -> Vec<usize> {
        let n = f.len();

        if n == 1 {
            return f;
        }

        let mut even = vec![0; n / 2];
        let mut odd = vec![0; n / 2];

        for i in 0..n / 2 {
            even[i] = f[2 * i];
            odd[i] = f[2 * i + 1];
        }

        even = intt(even, depth - 1);
        odd = intt(odd, depth - 1);

        let r = ROOT_INV[depth];
        let mut now = 1;

        for i in 0..n / 2 {
            odd[i] *= now;
            odd[i] %= MOD;
            f[i] = (even[i] + odd[i]) % MOD;
            f[i + n / 2] = (MOD + even[i] - odd[i]) % MOD;

            now *= r;
            now %= MOD;
        }

        return f;
    }

    pub fn conv(mut f: Vec<usize>, mut g: Vec<usize>) -> Vec<usize> {
        let mut l = 1;
        let mut d = 0;

        while f.len() + g.len() - 1 >= l {
            l <<= 1;
            d += 1;
        }

        while f.len() < l {
            f.push(0);
        }

        while g.len() < l {
            g.push(0);
        }

        assert!(f.len() == g.len());

        let F = ntt(f, d);
        let G = ntt(g, d);

        assert!(F.len() == G.len());

        let H = {
            let mut ret = vec![0; l];

            for i in 0..l {
                ret[i] = F[i] * G[i];
                ret[i] %= MOD;
            }

            ret
        };

        let h = {
            let mut ret = intt(H, d);

            let l_inv = inv_mod(l);

            for i in 0..l {
                ret[i] *= l_inv;
                ret[i] %= MOD;
            }

            ret
        };

        h
    }
}
0