結果
| 問題 |
No.526 フィボナッチ数列の第N項をMで割った余りを求める
|
| コンテスト | |
| ユーザー |
Yohei Tamura
|
| 提出日時 | 2020-09-19 18:13:39 |
| 言語 | Rust (1.83.0 + proconio) |
| 結果 |
AC
|
| 実行時間 | 2 ms / 2,000 ms |
| コード長 | 2,977 bytes |
| コンパイル時間 | 13,920 ms |
| コンパイル使用メモリ | 384,616 KB |
| 実行使用メモリ | 6,944 KB |
| 最終ジャッジ日時 | 2024-06-23 18:13:18 |
| 合計ジャッジ時間 | 15,013 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 12 |
ソースコード
#![allow(unused_imports)]
#![allow(unused_macros)]
use std::cmp::{max, min};
use std::collections::*;
use std::i64;
use std::io::{stdin, Read};
use std::usize;
trait ChMinMax {
fn chmin(&mut self, other: Self);
fn chmax(&mut self, other: Self);
}
impl<T> ChMinMax for T
where
T: PartialOrd,
{
fn chmin(&mut self, other: Self) {
if *self > other {
*self = other
}
}
fn chmax(&mut self, other: Self) {
if *self < other {
*self = other
}
}
}
#[allow(unused_macros)]
macro_rules! parse {
($it: ident ) => {};
($it: ident, ) => {};
($it: ident, $var:ident : $t:tt $($r:tt)*) => {
let $var = parse_val!($it, $t);
parse!($it $($r)*);
};
($it: ident, mut $var:ident : $t:tt $($r:tt)*) => {
let mut $var = parse_val!($it, $t);
parse!($it $($r)*);
};
($it: ident, $var:ident $($r:tt)*) => {
let $var = parse_val!($it, usize);
parse!($it $($r)*);
};
}
#[allow(unused_macros)]
macro_rules! parse_val {
($it: ident, [$t:tt; $len:expr]) => {
(0..$len).map(|_| parse_val!($it, $t)).collect::<Vec<_>>();
};
($it: ident, ($($t: tt),*)) => {
($(parse_val!($it, $t)),*)
};
($it: ident, u1) => {
$it.next().unwrap().parse::<usize>().unwrap() -1
};
($it: ident, $t: ty) => {
$it.next().unwrap().parse::<$t>().unwrap()
};
}
fn matmulmod(a: &[Vec<usize>], b: &[Vec<usize>], m: usize) -> Vec<Vec<usize>> {
assert_eq!(a[0].len(), b.len());
(0..a.len())
.map(|i| {
(0..b[0].len())
.map(|k| {
(0..b.len())
.map(|j| (a[i][j] * b[j][k]) % m)
.fold(0, |x, y| (x + y) % m)
})
.collect()
})
.collect()
}
fn idmat(n: usize) -> Vec<Vec<usize>> {
let mut ret = vec![vec![0; n]; n];
for i in 0..n {
ret[i][i] = 1;
}
ret
}
fn matpowmod(a: &Vec<Vec<usize>>, mut p: usize, m: usize) -> Vec<Vec<usize>> {
let n = a.len();
let mut ret = idmat(n);
let mut cur = a.clone();
while p > 0 {
if p & 1 == 1 {
ret = matmulmod(&ret, &cur, m);
}
cur = matmulmod(&cur, &cur, m);
p >>= 1;
}
ret
}
fn solve(s: &str) {
let mut it = s.split_whitespace();
parse!(it, n: usize, m: usize);
if n == 1 {
println!("{}", 0);
} else if n == 2 {
println!("{}", 1);
} else {
let a = vec![vec![1, 1], vec![1, 0]];
let b = matpowmod(&a, n - 2, m);
let v = vec![vec![1], vec![0]];
let w = matmulmod(&b, &v, m);
println!("{}", w[0][0]);
}
}
fn main() {
let mut s = String::new();
stdin().read_to_string(&mut s).unwrap();
solve(&s);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_input() {
let s = "
";
solve(s);
}
}
Yohei Tamura