From aa8477b45c0fdfc23ca180c60ebb744716fdd802 Mon Sep 17 00:00:00 2001 From: koba-e964 <3303362+koba-e964@users.noreply.github.com> Date: Sat, 29 Jun 2024 01:01:43 +0900 Subject: [PATCH] Add yukicoder/2798.rs yukicoder/2799.rs --- yukicoder/2798.rs | 170 ++++++++++++++++++++++++++++++++++++++++++++++ yukicoder/2799.rs | 64 +++++++++++++++++ 2 files changed, 234 insertions(+) create mode 100644 yukicoder/2798.rs create mode 100644 yukicoder/2799.rs diff --git a/yukicoder/2798.rs b/yukicoder/2798.rs new file mode 100644 index 00000000..ab786208 --- /dev/null +++ b/yukicoder/2798.rs @@ -0,0 +1,170 @@ +use std::io::Read; + +fn get_word() -> String { + let stdin = std::io::stdin(); + let mut stdin=stdin.lock(); + let mut u8b: [u8; 1] = [0]; + loop { + let mut buf: Vec = Vec::with_capacity(16); + loop { + let res = stdin.read(&mut u8b); + if res.unwrap_or(0) == 0 || u8b[0] <= b' ' { + break; + } else { + buf.push(u8b[0]); + } + } + if buf.len() >= 1 { + let ret = String::from_utf8(buf).unwrap(); + return ret; + } + } +} + +fn get() -> T { get_word().parse().ok().unwrap() } + +// https://judge.yosupo.jp/submission/5155 +mod pollard_rho { + /// binary gcd + pub fn gcd(mut x: i64, mut y: i64) -> i64 { + if y == 0 { return x; } + if x == 0 { return y; } + let k = (x | y).trailing_zeros(); + y >>= k; + x >>= x.trailing_zeros(); + while y != 0 { + y >>= y.trailing_zeros(); + if x > y { let t = x; x = y; y = t; } + y -= x; + } + x << k + } + + fn add_mod(x: i64, y: i64, n: i64) -> i64 { + let z = x + y; + if z >= n { z - n } else { z } + } + + fn mul_mod(x: i64, mut y: i64, n: i64) -> i64 { + assert!(x >= 0); + assert!(x < n); + let mut sum = 0; + let mut cur = x; + while y > 0 { + if (y & 1) == 1 { sum = add_mod(sum, cur, n); } + cur = add_mod(cur, cur, n); + y >>= 1; + } + sum + } + + fn mod_pow(x: i64, mut e: i64, n: i64) -> i64 { + let mut prod = if n == 1 { 0 } else { 1 }; + let mut cur = x % n; + while e > 0 { + if (e & 1) == 1 { prod = mul_mod(prod, cur, n); } + e >>= 1; + if e > 0 { cur = mul_mod(cur, cur, n); } + } + prod + } + + pub fn is_prime(n: i64) -> bool { + if n <= 1 { return false; } + let small = [2, 3, 5, 7, 11, 13]; + if small.iter().any(|&u| u == n) { return true; } + if small.iter().any(|&u| n % u == 0) { return false; } + let mut d = n - 1; + let e = d.trailing_zeros(); + d >>= e; + // https://miller-rabin.appspot.com/ + let a = [2, 325, 9375, 28178, 450775, 9780504, 1795265022]; + a.iter().all(|&a| { + if a % n == 0 { return true; } + let mut x = mod_pow(a, d, n); + if x == 1 { return true; } + for _ in 0..e { + if x == n - 1 { + return true; + } + x = mul_mod(x, x, n); + if x == 1 { return false; } + } + x == 1 + }) + } + + fn pollard_rho(n: i64, c: &mut i64) -> i64 { + // An improvement with Brent's cycle detection algorithm is performed. + // https://maths-people.anu.edu.au/~brent/pub/pub051.html + if n % 2 == 0 { return 2; } + loop { + let mut x: i64; // tortoise + let mut y = 2; // hare + let mut d = 1; + let cc = *c; + let f = |i| add_mod(mul_mod(i, i, n), cc, n); + let mut r = 1; + // We don't perform the gcd-once-in-a-while optimization + // because the plain gcd-every-time algorithm appears to + // outperform, at least on judge.yosupo.jp :) + while d == 1 { + x = y; + for _ in 0..r { + y = f(y); + d = gcd((x - y).abs(), n); + if d != 1 { break; } + } + r *= 2; + } + if d == n { + *c += 1; + continue; + } + return d; + } + } + + /// Outputs (p, e) in p's ascending order. + pub fn factorize(x: i64) -> Vec<(i64, usize)> { + if x <= 1 { return vec![]; } + let mut hm = std::collections::HashMap::new(); + let mut pool = vec![x]; + let mut c = 1; + while let Some(u) = pool.pop() { + if is_prime(u) { + *hm.entry(u).or_insert(0) += 1; + continue; + } + let p = pollard_rho(u, &mut c); + pool.push(p); + pool.push(u / p); + } + let mut v: Vec<_> = hm.into_iter().collect(); + v.sort(); + v + } +} // mod pollard_rho + +// Tags: partition-number +fn main() { + let n: i64 = get(); + let pe = pollard_rho::factorize(n); + const N: usize = 61; + let mut dp = vec![vec![0i64; N]; N]; + dp[0] = vec![1; N]; + for i in 1..N { + dp[i][1] = 1; + for j in 2..i + 1 { + dp[i][j] = dp[i][j - 1] + dp[i - j][j]; + } + for j in i + 1..N { + dp[i][j] = dp[i][j - 1]; + } + } + let mut ans = 1; + for (_, e) in pe { + ans *= dp[e][e]; + } + println!("{}", ans); +} diff --git a/yukicoder/2799.rs b/yukicoder/2799.rs new file mode 100644 index 00000000..5e7be139 --- /dev/null +++ b/yukicoder/2799.rs @@ -0,0 +1,64 @@ +// https://qiita.com/tanakh/items/0ba42c7ca36cd29d0ac8 +macro_rules! input { + ($($r:tt)*) => { + let stdin = std::io::stdin(); + let mut bytes = std::io::Read::bytes(std::io::BufReader::new(stdin.lock())); + let mut next = move || -> String{ + bytes.by_ref().map(|r|r.unwrap() as char) + .skip_while(|c|c.is_whitespace()) + .take_while(|c|!c.is_whitespace()) + .collect() + }; + input_inner!{next, $($r)*} + }; +} + +macro_rules! input_inner { + ($next:expr) => {}; + ($next:expr,) => {}; + ($next:expr, $var:ident : $t:tt $($r:tt)*) => { + let $var = read_value!($next, $t); + input_inner!{$next $($r)*} + }; +} + +macro_rules! read_value { + ($next:expr, [ $t:tt ; $len:expr ]) => { + (0..$len).map(|_| read_value!($next, $t)).collect::>() + }; + ($next:expr, $t:ty) => ($next().parse::<$t>().expect("Parse error")); +} + +// e.g., k = 3, 7 -> 1 6 -> 6 -> 3 3 -> 3 -> {} +fn dfs(a: i64, k: i64) -> i64 { + if a <= k { + return a; + } + if a % 2 == 0 { + 0 + } else { + -1 + } +} + +fn main() { + input! { + n: usize, k: i64, + a: [i64; n], + } + let sum: i64 = a.iter().sum(); + let mut prof = vec![]; + for a in a { + prof.push(dfs(a, k)); + } + prof.sort(); prof.reverse(); + let mut ans = 0; + for i in 0..n { + if i % 2 == 0 { + ans += prof[i]; + } else { + ans -= prof[i]; + } + } + println!("{}", (sum + ans) / 2); +}