結果
| 問題 | No.3670 Fast Knapsack |
| コンテスト | |
| ユーザー |
Moss_Local
|
| 提出日時 | 2026-09-04 23:14:35 |
| 言語 | Rust (1.97.1 + proconio + num + itertools) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 18,737 bytes |
| 記録 | |
| コンパイル時間 | 1,765 ms |
| コンパイル使用メモリ | 208,340 KB |
| 実行使用メモリ | 9,716 KB |
| 最終ジャッジ日時 | 2026-09-04 23:15:09 |
| 合計ジャッジ時間 | 9,349 ms |
|
ジャッジサーバーID (参考情報) |
judge4_0 / judge2_0 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 11 TLE * 1 -- * 13 |
コンパイルメッセージ
warning: variable does not need to be mutable
--> src/main.rs:51:17
|
51 | let mut $x = iter
| ----^^
| |
| help: remove this `mut`
...
720 | uin!(t);
| ------- in this macro invocation
|
= note: `#[warn(unused_mut)]` (part of `#[warn(unused)]`) on by default
= note: this warning originates in the macro `uin` (in Nightly builds, run with -Z macro-backtrace for more info)
warning: variable does not need to be mutable
--> src/main.rs:51:17
|
51 | let mut $x = iter
| ----^^
| |
| help: remove this `mut`
...
723 | uin!(n, s);
| ---------- in this macro invocation
|
= note: this warning originates in the macro `uin` (in Nightly builds, run with -Z macro-backtrace for more info)
warning: variable does not need to be mutable
--> src/main.rs:76:13
|
76 | let mut $x = read_vec::<usize>();
| ----^^
| |
| help: remove this `mut`
...
724 | inuv!(a);
| -------- in this macro invocation
|
= note: this warning originates in the macro `inuv` (in Nightly builds, run with -Z macro-backtrace for more info)
ソースコード
// -*- coding: utf-8-unix -*-
#![allow(dead_code, unused_imports, unused_macros, unused_variables)]
use std::cmp::{max, min, Ordering, Reverse};
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque};
use std::fmt::Debug;
use std::io::{self, Read};
use std::str::FromStr;
const INF_I32: i32 = 1_i32 << 30;
const INF_I64: i64 = 1_i64 << 60;
const INF_I128: i128 = 1_i128 << 120;
const INF_USIZE: usize = usize::MAX / 4;
const INF: i64 = INF_I64;
const UINF: usize = INF_USIZE;
const INF128: i128 = INF_I128;
const MOD1: i64 = 1_000_000_007;
const MOD9: i64 = 998_244_353;
const MOD: i64 = MOD9;
const UMOD: usize = MOD as usize;
// =============================================================================
// Input
// =========================================================================
#[allow(dead_code)]
fn read<T: std::str::FromStr>() -> T {
let mut s = String::new();
std::io::stdin().read_line(&mut s).ok();
s.trim().parse().ok().unwrap()
}
#[allow(dead_code)]
fn read_vec<T: std::str::FromStr>() -> Vec<T> {
read::<String>()
.split_whitespace()
.map(|e| e.parse().ok().unwrap())
.collect()
}
#[allow(dead_code)]
fn read_mat<T: std::str::FromStr>(n: usize) -> Vec<Vec<T>> {
(0..n).map(|_| read_vec()).collect()
}
macro_rules! uin {
($($x:ident),+ $(,)?) => {
let values = read_vec::<usize>();
let mut iter = values.into_iter();
$(
let mut $x = iter
.next()
.expect("入力の要素数が不足しています");
)+
};
}
macro_rules! iin {
($($x:ident),+ $(,)?) => {
let values = read_vec::<i64>();
let mut iter = values.into_iter();
$(
let mut $x = iter
.next()
.expect("入力の要素数が不足しています");
)+
};
}
macro_rules! cin {
($x:ident $(,)?) => {
let mut $x: Vec<char> = read::<String>().chars().collect();
};
}
macro_rules! inuv {
($x:ident $(,)?) => {
let mut $x = read_vec::<usize>();
};
}
macro_rules! iniv {
($x:ident $(,)?) => {
let mut $x = read_vec::<i64>();
};
}
// =============================================================================
// Output / Debug
// =============================================================================
macro_rules! p {
() => {
println!();
};
($value:expr $(,)?) => {
println!("{}", $value);
};
($fmt:literal, $($arg:tt)*) => {
println!($fmt, $($arg)*);
};
}
macro_rules! join {
($iter:expr, $separator:expr $(,)?) => {
($iter)
.into_iter()
.map(|x| x.to_string())
.collect::<Vec<_>>()
.join($separator)
};
}
macro_rules! pv {
($iter:expr $(,)?) => {
println!("{}", join!($iter, " "));
};
($iter:expr, $separator:expr $(,)?) => {
println!("{}", join!($iter, $separator));
};
}
macro_rules! yesno {
($condition:expr $(,)?) => {
println!("{}", if $condition { "Yes" } else { "No" });
};
($condition:expr, $yes:expr, $no:expr $(,)?) => {
println!("{}", if $condition { $yes } else { $no });
};
}
macro_rules! d {
($($value:expr),+ $(,)?) => {
#[cfg(debug_assertions)]
{
eprint!("[{}:{}]", file!(), line!());
$(
eprint!(" {} = {:?}", stringify!($value), &$value);
)+
eprintln!();
}
};
}
// =============================================================================
// Scalar / Vec utilities
// =============================================================================
macro_rules! chmin {
($base:expr, $($value:expr),+ $(,)?) => {{
let mut updated = false;
$(
let value = $value;
if $base > value {
$base = value;
updated = true;
}
)+
updated
}};
}
macro_rules! chmax {
($base:expr, $($value:expr),+ $(,)?) => {{
let mut updated = false;
$(
let value = $value;
if $base < value {
$base = value;
updated = true;
}
)+
updated
}};
}
macro_rules! min {
// collection: Vec、配列、スライスなど
($iter:expr $(,)?) => {{
($iter)
.iter()
.min()
.cloned()
.expect("min! called on an empty iterator")
}};
// 複数の値
($first:expr, $($rest:expr),+ $(,)?) => {{
let mut answer = ($first).clone();
$(
chmin!(answer, ($rest).clone());
)+
answer
}};
}
macro_rules! max {
// collection: Vec、配列、スライスなど
($iter:expr $(,)?) => {{
($iter)
.iter()
.max()
.cloned()
.expect("max! called on an empty iterator")
}};
// 複数の値
($first:expr, $($rest:expr),+ $(,)?) => {{
let mut answer = ($first).clone();
$(
chmax!(answer, ($rest).clone());
)+
answer
}};
}
macro_rules! ndvec {
($value:expr; $len:expr) => {
vec![$value; $len]
};
($value:expr; $len:expr, $($rest:expr),+ $(,)?) => {
vec![ndvec![$value; $($rest),+]; $len]
};
}
macro_rules! prefix_sum {
($values:expr $(,)?) => {{
let values = &$values;
let mut prefix = Vec::with_capacity(values.len() + 1);
prefix.push(Default::default());
for &value in values.iter() {
let next = prefix.last().copied().unwrap() + value;
prefix.push(next);
}
prefix
}};
}
// 数学的な floor(a / b)。b != 0。
macro_rules! div_floor {
($a:expr, $b:expr $(,)?) => {{
let a = $a;
let b = $b;
let q = a / b;
let r = a % b;
if r != 0 && ((r > 0) != (b > 0)) {
q - 1
} else {
q
}
}};
}
// 数学的な ceil(a / b)。b != 0。
macro_rules! div_ceil {
($a:expr, $b:expr $(,)?) => {{
let a = $a;
let b = $b;
let q = a / b;
let r = a % b;
if r != 0 && ((r > 0) == (b > 0)) {
q + 1
} else {
q
}
}};
}
// =============================================================================
// Integer / floating-point binary search
// =============================================================================
// pred(ok) == true, pred(ng) == false を保ち、最後に true 側の境界を返す。
// ok < ng と ok > ng の双方に対応する。
macro_rules! binsearch {
(ok = $ok:expr, ng = $ng:expr, $pred:expr $(,)?) => {{
let mut ok = $ok;
let mut ng = $ng;
let mut pred = $pred;
while ok.abs_diff(ng) > 1 {
let mid = if ok < ng {
ok + (ng - ok) / 2
} else {
ng + (ok - ng) / 2
};
if pred(mid) {
ok = mid;
} else {
ng = mid;
}
}
ok
}};
}
// false ... true の単調列に対し、最初の true を返す。
// ng は false 側の番兵、ok は true 側の番兵。
macro_rules! first_true {
($ng:expr, $ok:expr, $pred:expr $(,)?) => {
binsearch!(ok = $ok, ng = $ng, $pred)
};
}
// true ... false の単調列に対し、最後の true を返す。
// ok は true 側の番兵、ng は false 側の番兵。
macro_rules! last_true {
($ok:expr, $ng:expr, $pred:expr $(,)?) => {
binsearch!(ok = $ok, ng = $ng, $pred)
};
}
// 浮動小数点版。回数を明示することで停止条件の曖昧さを避ける。
macro_rules! binsearch_f64 {
(ok = $ok:expr, ng = $ng:expr, iter = $iter:expr, $pred:expr $(,)?) => {{
let mut ok = $ok;
let mut ng = $ng;
let mut pred = $pred;
for _ in 0..$iter {
let mid = (ok + ng) * 0.5;
if pred(mid) {
ok = mid;
} else {
ng = mid;
}
}
ok
}};
}
// =============================================================================
// Sorted slice bounds
// =============================================================================
macro_rules! lower_bound {
($slice:expr, $value:expr $(,)?) => {{
let value = $value;
($slice).partition_point(|x| x < &value)
}};
}
macro_rules! upper_bound {
($slice:expr, $value:expr $(,)?) => {{
let value = $value;
($slice).partition_point(|x| x <= &value)
}};
}
// UTIL
macro_rules! neighbors4 {
($y:expr, $x:expr, $h:expr, $w:expr $(,)?) => {{
const DY: [isize; 4] = [-1, 0, 1, 0];
const DX: [isize; 4] = [0, 1, 0, -1];
(0..4).filter_map(move |dir| {
let ny = $y as isize + DY[dir];
let nx = $x as isize + DX[dir];
if 0 <= ny && ny < $h as isize && 0 <= nx && nx < $w as isize {
Some((ny as usize, nx as usize))
} else {
None
}
})
}};
}
macro_rules! run_length {
($iter:expr $(,)?) => {{
let mut result = Vec::new();
for value in $iter {
match result.last_mut() {
Some((last, count)) if *last == value => {
*count += 1usize;
}
_ => {
result.push((value, 1usize));
}
}
}
result
}};
}
macro_rules! vector_compress {
($iter:expr $(,)?) => {{
let values: Vec<_> = ($iter).into_iter().collect();
let mut coordinates = values.clone();
coordinates.sort();
coordinates.dedup();
let compressed = values
.iter()
.map(|value| coordinates.binary_search(value).unwrap())
.collect::<Vec<_>>();
(compressed, coordinates)
}};
}
// =============================================================================
// Map / Set literals and counters
// =============================================================================
macro_rules! map {
($($key:expr => $value:expr),* $(,)?) => {{
let mut map = ::std::collections::BTreeMap::new();
$(map.insert($key, $value);)*
map
}};
}
macro_rules! set {
($($value:expr),* $(,)?) => {{
let mut set = ::std::collections::BTreeSet::new();
$(set.insert($value);)*
set
}};
}
macro_rules! count_map {
($iter:expr $(,)?) => {{
let mut count = BTreeMap::new();
for value in $iter {
*count.entry(value).or_insert(0usize) += 1;
}
count
}};
}
macro_rules! map_add {
($map:expr, $key:expr, $delta:expr $(,)?) => {{
let key = $key;
let delta = $delta;
let map = &mut $map;
*map.entry(key).or_insert(0) += delta;
}};
}
macro_rules! map_inc {
($map:expr, $key:expr $(,)?) => {
map_add!($map, $key, 1)
};
}
macro_rules! map_sub {
($map:expr, $key:expr, $delta:expr $(,)?) => {{
let key = $key;
let delta = $delta;
let map = &mut $map;
let remove = match map.get_mut(&key) {
Some(value) => {
if *value <= delta {
true
} else {
*value -= delta;
false
}
}
None => false,
};
if remove {
map.remove(&key);
true
} else {
false
}
}};
}
macro_rules! map_dec {
($map:expr, $key:expr $(,)?) => {
map_sub!($map, $key, 1)
};
}
macro_rules! sum {
($iter:expr $(,)?) => {{
let mut sum = 0;
for &value in ($iter).iter() {
sum += value;
}
sum
}};
}
pub struct Dsu {
n: usize,
// root node: -1 * component size
// otherwise: parent
parent_or_size: Vec<i32>,
}
impl Dsu {
// 0 <= size <= 10^8 is constrained.
pub fn new(size: usize) -> Self {
Self {
n: size,
parent_or_size: vec![-1; size],
}
}
pub fn merge(&mut self, a: usize, b: usize) -> usize {
assert!(a < self.n);
assert!(b < self.n);
let (mut x, mut y) = (self.leader(a), self.leader(b));
if x == y {
return x;
}
if -self.parent_or_size[x] < -self.parent_or_size[y] {
std::mem::swap(&mut x, &mut y);
}
self.parent_or_size[x] += self.parent_or_size[y];
self.parent_or_size[y] = x as i32;
x
}
pub fn same(&mut self, a: usize, b: usize) -> bool {
assert!(a < self.n);
assert!(b < self.n);
self.leader(a) == self.leader(b)
}
pub fn leader(&mut self, a: usize) -> usize {
assert!(a < self.n);
if self.parent_or_size[a] < 0 {
return a;
}
self.parent_or_size[a] = self.leader(self.parent_or_size[a] as usize) as i32;
self.parent_or_size[a] as usize
}
pub fn size(&mut self, a: usize) -> usize {
assert!(a < self.n);
let x = self.leader(a);
-self.parent_or_size[x] as usize
}
pub fn groups(&mut self) -> Vec<Vec<usize>> {
let mut leader_buf = vec![0; self.n];
let mut group_size = vec![0; self.n];
for i in 0..self.n {
leader_buf[i] = self.leader(i);
group_size[leader_buf[i]] += 1;
}
let mut result = vec![Vec::new(); self.n];
for i in 0..self.n {
result[i].reserve(group_size[i]);
}
for i in 0..self.n {
result[leader_buf[i]].push(i);
}
result
.into_iter()
.filter(|x| !x.is_empty())
.collect::<Vec<Vec<usize>>>()
}
}
const TRUE: &bool = &true;
const FALSE: &bool = &false;
#[derive(Clone, Debug)]
/// Efficient bool collection
pub struct BitSet {
buf: Vec<u64>,
size: usize,
}
impl BitSet {
#[allow(dead_code)]
pub fn new(size: usize) -> BitSet {
BitSet {
buf: vec![0; (size + 63) / 64],
size,
}
}
#[allow(dead_code)]
pub fn set(&mut self, i: usize, b: bool) {
assert!(i < self.size);
if b {
self.buf[i >> 6] |= 1 << (i & 63);
} else {
self.buf[i >> 6] &= !(1 << (i & 63));
}
}
#[allow(dead_code)]
pub fn count_ones(&self) -> u32 {
self.buf.iter().map(|x| x.count_ones()).sum()
}
#[allow(dead_code)]
fn chomp(&mut self) {
let r = self.size & 63;
if r != 0 {
if let Some(x) = self.buf.last_mut() {
let d = 64 - r;
*x = (*x << d) >> d;
}
}
}
}
impl std::ops::Index<usize> for BitSet {
type Output = bool;
fn index(&self, index: usize) -> &bool {
[FALSE, TRUE][(self.buf[index >> 6] >> (index & 63)) as usize & 1]
}
}
#[allow(clippy::suspicious_op_assign_impl)]
impl std::ops::ShlAssign<usize> for BitSet {
fn shl_assign(&mut self, x: usize) {
let q = x >> 6;
let r = x & 63;
if q >= self.buf.len() {
for x in &mut self.buf {
*x = 0;
}
return;
}
if r == 0 {
for i in (q..self.buf.len()).rev() {
self.buf[i] = self.buf[i - q];
}
} else {
for i in (q + 1..self.buf.len()).rev() {
self.buf[i] = (self.buf[i - q] << r) | (self.buf[i - q - 1] >> (64 - r));
}
self.buf[q] = self.buf[0] << r;
}
for x in &mut self.buf[..q] {
*x = 0;
}
self.chomp();
}
}
impl std::ops::Shl<usize> for BitSet {
type Output = Self;
fn shl(mut self, x: usize) -> Self {
self <<= x;
self
}
}
#[allow(clippy::suspicious_op_assign_impl)]
impl std::ops::ShrAssign<usize> for BitSet {
fn shr_assign(&mut self, x: usize) {
let q = x >> 6;
let r = x & 63;
if q >= self.buf.len() {
for x in &mut self.buf {
*x = 0;
}
return;
}
if r == 0 {
for i in 0..self.buf.len() - q {
self.buf[i] = self.buf[i + q];
}
} else {
for i in 0..self.buf.len() - q - 1 {
self.buf[i] = (self.buf[i + q] >> r) | (self.buf[i + q + 1] << (64 - r));
}
let len = self.buf.len();
self.buf[len - q - 1] = self.buf[len - 1] >> r;
}
let len = self.buf.len();
for x in &mut self.buf[len - q..] {
*x = 0;
}
}
}
impl std::ops::Shr<usize> for BitSet {
type Output = Self;
fn shr(mut self, x: usize) -> Self {
self >>= x;
self
}
}
impl<'a> std::ops::BitAndAssign<&'a BitSet> for BitSet {
fn bitand_assign(&mut self, rhs: &'a Self) {
for (a, b) in self.buf.iter_mut().zip(rhs.buf.iter()) {
*a &= *b;
}
}
}
impl<'a> std::ops::BitAnd<&'a BitSet> for BitSet {
type Output = Self;
fn bitand(mut self, rhs: &'a Self) -> Self {
self &= rhs;
self
}
}
impl<'a> std::ops::BitOrAssign<&'a BitSet> for BitSet {
fn bitor_assign(&mut self, rhs: &'a Self) {
for (a, b) in self.buf.iter_mut().zip(rhs.buf.iter()) {
*a |= *b;
}
self.chomp();
}
}
impl<'a> std::ops::BitOr<&'a BitSet> for BitSet {
type Output = Self;
fn bitor(mut self, rhs: &'a Self) -> Self {
self |= rhs;
self
}
}
impl<'a> std::ops::BitXorAssign<&'a BitSet> for BitSet {
fn bitxor_assign(&mut self, rhs: &'a Self) {
for (a, b) in self.buf.iter_mut().zip(rhs.buf.iter()) {
*a ^= *b;
}
self.chomp();
}
}
impl<'a> std::ops::BitXor<&'a BitSet> for BitSet {
type Output = Self;
fn bitxor(mut self, rhs: &'a Self) -> Self {
self ^= rhs;
self
}
}
fn main() {
uin!(t);
for _ in 0..t {
uin!(n, s);
inuv!(a);
let mut dp = BitSet::new(s + 1);
dp.set(0, true);
for x in a {
if x > s {
continue;
}
let shifted = dp.clone() << x;
dp |= &shifted;
}
let mut ans = 0;
for x in (0..=s).rev() {
if dp[x] {
ans = x;
break;
}
}
println!("{}", ans);
}
}
Moss_Local