2023-07-12 bouzuya/rust-atcoder で cargo workspace を適用してみた / M-SOLUTIONS プロコンオープン A, B, C を解いた
bouzuya/rust-atcoder で cargo workspace を適用してみた。
cargo-atcoder で dependencies をコンテストごとに取得していて無駄そうだったので target/
を共有してみようと思った。これは cargo-compete がそうしているから。
cargo-compete では .cargo/config.toml
で build.target-dir
を指定することで target/
の共有を実現している。ぼくは cargo workspace でできるんじゃないかと思って試してみた。
結論としては cargo workspace だとまずかった。まずかったのは 2 点。
- bin の name が一意でないと警告が出る
- rust-analyzer が cargo workspace の members すべてを見に行く
結果的にコンテストごとに dependencies を取得する時間の無駄よりもっとまずそうな動きになった。 VS Code の動きがカクついたりする。
結局 cargo workspace をやめて .cargo/config.toml
に target-dir
を指定することにした。これは cargo-compete と同じ方法だ。
あとから教えてもらったことだけどこの方法は cargo-atcoder の README に書いてある。
嘘でしょ……。
cargo-atcoder は使い慣れているのだけど problem 単位での操作が難しいので自分で何かつくってみようかと思っている。つくることで今回のような学びがありそうな気がしている。
M-SOLUTIONS プロコンオープン
- A - Sum of Interior Angles
https://atcoder.jp/contests/m-solutions2019/tasks/m_solutions2019_a
- 提出: https://atcoder.jp/contests/m-solutions2019/submissions/43492789
(n - 2) * 180
- B - Sumo
https://atcoder.jp/contests/m-solutions2019/tasks/m_solutions2019_b
- 提出: https://atcoder.jp/contests/m-solutions2019/submissions/43492845
((15 - s.len()) + s.into_iter().filter(|&c| c == 'o').count()) >= 8
- C - Best-of-(2n-1)
https://atcoder.jp/contests/m-solutions2019/tasks/m_solutions2019_c
- 提出: https://atcoder.jp/contests/m-solutions2019/submissions/43493047
- 解説 AC
- 問題を設計した人は二項係数の前計算と引き分けの部分がすこしややこしいくらいの気持ちで配置していそう (C 問題なので計算量を意識する程度の問題のはず)
- ……が、想定通りの式を適切に立てられる人間がほとんどいなかったせいか黄 diff になっている
- D - Maximum Sum of Minimum
https://atcoder.jp/contests/m-solutions2019/tasks/m_solutions2019_d
- 着手したかったが C で時間切れ
use modint::ModInt1000000007 as ModInt;
use proconio::input;
fn main() {
input! {
n: usize,
a: usize,
b: usize,
c: usize,
};
let (fact, finv) = {
let maxn = 2 * n;
let mut fact = vec![ModInt::new(1); maxn + 1];
for i in 1..=maxn {
fact[i] = fact[i - 1] * ModInt::new(i);
}
let mut finv = vec![ModInt::new(1); maxn + 1];
finv[maxn] = fact[maxn].inv();
for i in (1..=maxn).rev() {
finv[i - 1] = finv[i] * ModInt::new(i);
}
(fact, finv)
};
let binom = |n: usize, k: usize| -> ModInt {
if n < k {
ModInt::new(0)
} else {
fact[n] * finv[k] * finv[n - k]
}
};
let a = ModInt::new(a);
let b = ModInt::new(b);
let c = ModInt::new(c);
let mut ans = ModInt::new(0);
for m in n..=2 * n - 1 {
ans += binom(m - 1, n - 1)
* (((a.pow(n as u64) * b.pow((m - n) as u64)
+ a.pow((m - n) as u64) * b.pow(n as u64))
* ModInt::new(m)
* ModInt::new(100))
/ ((a + b).pow(m as u64) * (ModInt::new(100) - c)));
}
println!("{}", ans);
}
// modint
今日のコミット。