結果
問題 |
No.3302 Sense Battle
|
ユーザー |
|
提出日時 | 2025-10-05 16:12:23 |
言語 | Rust (1.83.0 + proconio) |
結果 |
TLE
|
実行時間 | - |
コード長 | 6,331 bytes |
コンパイル時間 | 12,035 ms |
コンパイル使用メモリ | 401,844 KB |
実行使用メモリ | 10,148 KB |
最終ジャッジ日時 | 2025-10-05 16:12:40 |
合計ジャッジ時間 | 17,117 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 1 TLE * 1 -- * 16 |
コンパイルメッセージ
warning: methods `get_slice`, `max_right`, and `min_left` are never used --> src/main.rs:119:12 | 104 | impl<M: Monoid> Segtree<M> { | -------------------------- methods in this implementation ... 119 | pub fn get_slice(&self) -> &[M::S] { | ^^^^^^^^^ ... 170 | pub fn max_right<F>(&self, mut l: usize, f: F) -> usize | ^^^^^^^^^ ... 208 | pub fn min_left<F>(&self, mut r: usize, f: F) -> usize | ^^^^^^^^ | = note: `#[warn(dead_code)]` on by default
ソースコード
use std::u64; use proconio::input; use segment_tree::{Max, Segtree}; fn solve() -> u64 { input! { n: usize, ab: [(u64, u64); n], } let mut table = Segtree::<Max<u64>>::new(n + 1); table.set(0, 0); for &(ai, bi) in ab.iter() { let mut ntable = Segtree::<Max<u64>>::new(n + 1); for i in 0..n { ntable.set(i.saturating_sub(1), table.get(i) + bi); } for i in 0..=n { let mx0 = table.prod(..=i); let mx1 = ntable.get(i); ntable.set(i, mx1.max(mx0 + ai * i as u64)); } table = ntable; } table.get(0) } fn main() { let ans = solve(); println!("{}", ans); } mod segment_tree { use std::{cmp, convert::Infallible, marker::PhantomData, ops::{Bound, RangeBounds}}; // from https://github.com/rust-lang-ja/ac-library-rs/blob/master/src/internal_bit.rs pub(crate) fn ceil_pow2(n: u32) -> u32 { 32 - n.saturating_sub(1).leading_zeros() } // from https://github.com/rust-lang-ja/ac-library-rs/blob/master/src/internal_type_traits.rs pub trait BoundedBelow { fn min_value() -> Self; } impl BoundedBelow for u64 { #[inline] fn min_value() -> Self { Self::MIN } } // from https://github.com/rust-lang-ja/ac-library-rs/blob/master/src/segtree.rs pub trait Monoid { type S: Clone; fn identity() -> Self::S; fn binary_operation(a: &Self::S, b: &Self::S) -> Self::S; } pub struct Max<S>(Infallible, PhantomData<fn() -> S>); impl<S> Monoid for Max<S> where S: Copy + Ord + BoundedBelow, { type S = S; fn identity() -> Self::S { S::min_value() } fn binary_operation(a: &Self::S, b: &Self::S) -> Self::S { cmp::max(*a, *b) } } impl<M: Monoid> Default for Segtree<M> { fn default() -> Self { Segtree::new(0) } } impl<M: Monoid> Segtree<M> { pub fn new(n: usize) -> Segtree<M> { vec![M::identity(); n].into() } } impl<M: Monoid> From<Vec<M::S>> for Segtree<M> { fn from(v: Vec<M::S>) -> Self { let n = v.len(); let log = ceil_pow2(n as u32) as usize; let size = 1 << log; let mut d = vec![M::identity(); 2 * size]; d[size..][..n].clone_from_slice(&v); let mut ret = Segtree { n, size, log, d }; for i in (1..size).rev() { ret.update(i); } ret } } impl<M: Monoid> FromIterator<M::S> for Segtree<M> { fn from_iter<T: IntoIterator<Item = M::S>>(iter: T) -> Self { let v = iter.into_iter().collect::<Vec<_>>(); v.into() } } impl<M: Monoid> Segtree<M> { pub fn set(&mut self, mut p: usize, x: M::S) { assert!(p < self.n); p += self.size; self.d[p] = x; for i in 1..=self.log { self.update(p >> i); } } pub fn get(&self, p: usize) -> M::S { assert!(p < self.n); self.d[p + self.size].clone() } pub fn get_slice(&self) -> &[M::S] { &self.d[self.size..][..self.n] } pub fn prod<R>(&self, range: R) -> M::S where R: RangeBounds<usize>, { // Trivial optimization if range.start_bound() == Bound::Unbounded && range.end_bound() == Bound::Unbounded { return self.all_prod(); } let mut r = match range.end_bound() { Bound::Included(r) => r + 1, Bound::Excluded(r) => *r, Bound::Unbounded => self.n, }; let mut l = match range.start_bound() { Bound::Included(l) => *l, Bound::Excluded(l) => l + 1, // TODO: There are another way of optimizing [0..r) Bound::Unbounded => 0, }; assert!(l <= r && r <= self.n); let mut sml = M::identity(); let mut smr = M::identity(); l += self.size; r += self.size; while l < r { if l & 1 != 0 { sml = M::binary_operation(&sml, &self.d[l]); l += 1; } if r & 1 != 0 { r -= 1; smr = M::binary_operation(&self.d[r], &smr); } l >>= 1; r >>= 1; } M::binary_operation(&sml, &smr) } pub fn all_prod(&self) -> M::S { self.d[1].clone() } pub fn max_right<F>(&self, mut l: usize, f: F) -> usize where F: Fn(&M::S) -> bool, { assert!(l <= self.n); assert!(f(&M::identity())); if l == self.n { return self.n; } l += self.size; let mut sm = M::identity(); while { // do while l % 2 == 0 { l >>= 1; } if !f(&M::binary_operation(&sm, &self.d[l])) { while l < self.size { l *= 2; let res = M::binary_operation(&sm, &self.d[l]); if f(&res) { sm = res; l += 1; } } return l - self.size; } sm = M::binary_operation(&sm, &self.d[l]); l += 1; // while { let l = l as isize; (l & -l) != l } } {} self.n } pub fn min_left<F>(&self, mut r: usize, f: F) -> usize where F: Fn(&M::S) -> bool, { assert!(r <= self.n); assert!(f(&M::identity())); if r == 0 { return 0; } r += self.size; let mut sm = M::identity(); while { // do r -= 1; while r > 1 && r % 2 == 1 { r >>= 1; } if !f(&M::binary_operation(&self.d[r], &sm)) { while r < self.size { r = 2 * r + 1; let res = M::binary_operation(&self.d[r], &sm); if f(&res) { sm = res; r -= 1; } } return r + 1 - self.size; } sm = M::binary_operation(&self.d[r], &sm); // while { let r = r as isize; (r & -r) != r } } {} 0 } fn update(&mut self, k: usize) { self.d[k] = M::binary_operation(&self.d[2 * k], &self.d[2 * k + 1]); } } // Maybe we can use this someday // ``` // for i in 0..=self.log { // for j in 0..1 << i { // print!("{}\t", self.d[(1 << i) + j]); // } // println!(); // } // ``` #[derive(Clone)] pub struct Segtree<M> where M: Monoid, { // variable name is _n in original library n: usize, size: usize, log: usize, d: Vec<M::S>, } }