Skip to content

Commit

Permalink
Add yukicoder/1349.rs yukicoder/1803.rs
Browse files Browse the repository at this point in the history
  • Loading branch information
koba-e964 committed Aug 27, 2023
1 parent e8fb1d5 commit fde49c7
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 0 deletions.
73 changes: 73 additions & 0 deletions yukicoder/1349.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#[allow(unused_imports)]
use std::cmp::*;
#[allow(unused_imports)]
use std::collections::*;
use std::io::{Write, BufWriter};
// 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),* )) => { ($(read_value!($next, $t)),*) };
($next:expr, [ $t:tt ; $len:expr ]) => {
(0..$len).map(|_| read_value!($next, $t)).collect::<Vec<_>>()
};
($next:expr, usize1) => (read_value!($next, usize) - 1);
($next:expr, $t:ty) => ($next().parse::<$t>().expect("Parse error"));
}

trait Change { fn chmax(&mut self, x: Self); fn chmin(&mut self, x: Self); }
impl<T: PartialOrd> Change for T {
fn chmax(&mut self, x: T) { if *self < x { *self = x; } }
fn chmin(&mut self, x: T) { if *self > x { *self = x; } }
}

// https://yukicoder.me/problems/no/1349 (3.5, 解説を見た)
// N 個の要素を大きさ 10 程度のブロックに分割して、ブロックごとに区間和を持つと N^2/200 エントリで済む。
// -> 解説を見た。dp[i][j] := min {x | [i, x] で j を作れる} とし、
// dp[i][k * a[i]] <- dp[i + 1][k] という DP をする。
// -> a[i] を使わない遷移 (dp[i][k] <- dp[i + 1][k]) を忘れて WA。
// The author read the editorial before implementing this.
// Tags: idea, queries
fn main() {
let out = std::io::stdout();
let mut out = BufWriter::new(out.lock());
macro_rules! puts {($($format:tt)*) => (let _ = write!(out,$($format)*););}
input! {
n: usize, q: usize, p: usize,
a: [usize; n],
lrk: [(usize1, usize, usize); q],
}
let mut dp = vec![vec![n; p]; n + 1];
for i in (0..n).rev() {
dp[i][a[i]] = i;
for j in 0..p {
let tmp = dp[i + 1][j];
dp[i][(j * a[i]) % p].chmin(tmp);
dp[i][j].chmin(tmp);
}
}
for (l, r, k) in lrk {
puts!("{}\n", if dp[l][k] < r { "Yes" } else { "No" });
}
}
47 changes: 47 additions & 0 deletions yukicoder/1803.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
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/1803 (3.5)
// 問題のコスト関数を重みとした完全グラフの最小全域木の重みが答え。M < N のとき、i と M - i、M - i と M + i がコスト 0 で繋がるので、i と M + i がコスト 0 で繋がる。(1 <= i <= N - M)
// M - i と i が繋がることから、頂点番号が M / 2 よりも大きい頂点は、自分未満の番号の頂点のいずれかと繋がるので、代表としては頂点番号 M / 2 以下のものだけを考えれば良い。(例外は M)
// またコストを考えるとき、使う頂点としては i と M-i のみを考えれば良い。なぜなら M+i を使うときのコストと i を使うときのコストは同じであるため。
// N >= M であれば、コスト 0 で繋げられる頂点を繋げた後の連結成分の個数は floor(M / 2) + 1 個。
// このとき (1, M), (2, M - 1), ... と繋ぐことでコスト floor(M / 2) で連結にできる。
// M / 2 <= N < M の場合、連結成分は floor(M / 2) 個である。
// コスト 1 の辺 (M - N + 1, N), ..., (floor(M / 2), M + 1 - floor(M / 2)) をつないだ後、残る連結成分は 1, 2, ..., M - N の M-N 個である。
// このようになったら 1 と他全てを繋ぐのが最善なので、必要なコストの合計は floor(M / 2) - (M - N) + (M - N + 1)(M - N + 2) / 2 - 3 である。
// Tags: minimum-spanning-trees, math
fn main() {
let t: usize = get();
for _ in 0..t {
let n: i64 = get();
let m: i64 = get();
if n >= m {
println!("{}", m / 2);
continue;
}
println!("{}", (m / 2) - (m - n) + (m - n + 1) * (m - n + 2) / 2 - 3);
}
}

0 comments on commit fde49c7

Please sign in to comment.