Skip to content

Commit

Permalink
Add yukicoder/2846.rs yukicoder/2847.rs
Browse files Browse the repository at this point in the history
  • Loading branch information
koba-e964 committed Aug 25, 2024
1 parent 1868a3b commit 8770313
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 0 deletions.
55 changes: 55 additions & 0 deletions yukicoder/2846.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
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<u8> = 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: std::str::FromStr>() -> T { get_word().parse().ok().unwrap() }

// https://yukicoder.me/problems/no/2846 (3)
// irb(main):009> [24,22,21,20,18,16,15,14,13,12,11,10,9,8,7,6,5].reduce{|a,b|a.lcm(b)}
// => 720720
// 素数 23, 19, 17 だけ特別扱いして、あとは幅 720720 の DP で解く。
fn main() {
let k: usize = get();
let n: usize = get();
const W: usize = 720_720;
let prs = [23, 19, 17];
let mut dp = vec![0i64; W + 1];
dp[0] = 1;
for _ in 0..k {
let mut ep = vec![0; W + 1];
for i in 1..n + 1 {
if W % i != 0 { continue; }
let x = W / i;
for j in x..W + 1 {
ep[j] += dp[j - x];
}
}
dp = ep;
}
let mut ans = dp[W];
for &p in &prs {
if k == p {
ans += 1;
}
}
println!("{}", ans);
}
77 changes: 77 additions & 0 deletions yukicoder/2847.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
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<u8> = 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: std::str::FromStr>() -> T { get_word().parse().ok().unwrap() }

fn gcd(a: i64, b: i64) -> i64 {
if b == 0 {
a
} else {
gcd(b, a % b)
}
}

fn calc(x: i64, y: i64, a: i64, b: i64) -> i64 {
(x - a).max(0) * (y - b).max(0)
}

// https://yukicoder.me/problems/no/2847 (3.5)
// a^2 + b^2 が平方数となる (a, b) 全てに対して、(2 * a, 2 * b) だけ離れた点を数える必要がある。
// a^2 + b^2 が平方数となる (a, b) の列挙は、1+i や有理整数で割り切れないガウス整数を列挙することで行える。
// Tags: enumerating-gaussian-integers-with-square-norm
fn main() {
let x: i64 = get();
let y: i64 = get();
let m: i64 = get();
let mut tot = 0;
for a in 1..=x / 2 {
tot += calc(x, y, 2 * a, 0);
tot %= m;
}
for a in 1..=y / 2 {
tot += calc(x, y, 0, 2 * a);
tot %= m;
}
for a in 1..2001 {
for b in 1..2001 {
if (a + b) % 2 == 0 {
continue;
}
if gcd(a, b) != 1 {
continue;
}
let c = a * a - b * b;
let d = 2 * a * b;
let (c, d) = if c < 0 {
(d, -c)
} else {
(c, d)
};
for s in 1..=(x / 2 / c).min(y / 2 / d) {
tot += calc(x, y, c * 2 * s, d * 2 * s) * 2;
tot %= m;
}
}
}
println!("{}", tot * 2 % m);
}

0 comments on commit 8770313

Please sign in to comment.