結果
| 問題 |
No.2620 Sieve of Coins
|
| コンテスト | |
| ユーザー |
akakimidori
|
| 提出日時 | 2024-01-26 22:00:09 |
| 言語 | Rust (1.83.0 + proconio) |
| 結果 |
AC
|
| 実行時間 | 178 ms / 2,000 ms |
| コード長 | 5,096 bytes |
| コンパイル時間 | 13,872 ms |
| コンパイル使用メモリ | 378,676 KB |
| 実行使用メモリ | 12,428 KB |
| 最終ジャッジ日時 | 2024-09-28 08:09:14 |
| 合計ジャッジ時間 | 20,452 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 5 |
| other | AC * 53 |
コンパイルメッセージ
warning: unused import: `std::io::Write`
--> src/main.rs:9:5
|
9 | use std::io::Write;
| ^^^^^^^^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
warning: type alias `Map` is never used
--> src/main.rs:11:6
|
11 | type Map<K, V> = BTreeMap<K, V>;
| ^^^
|
= note: `#[warn(dead_code)]` on by default
warning: type alias `Set` is never used
--> src/main.rs:12:6
|
12 | type Set<T> = BTreeSet<T>;
| ^^^
warning: type alias `Deque` is never used
--> src/main.rs:13:6
|
13 | type Deque<T> = VecDeque<T>;
| ^^^^^
warning: function `test` is never used
--> src/main.rs:81:4
|
81 | fn test() {
| ^^^^
ソースコード
// N=1, A_1 = 1 の場合はどうなるか
// 1, 素数、...
// 平方数持たないことが表になる条件
// N=1の場合はこれでいい
// 1, 2 の場合はどうなるのか
//
use std::collections::*;
use std::io::Write;
type Map<K, V> = BTreeMap<K, V>;
type Set<T> = BTreeSet<T>;
type Deque<T> = VecDeque<T>;
fn main() {
input! {
l: usize,
n: usize,
a: [usize; n],
}
let calc = |l: usize| -> usize {
if l == 0 {
return 0;
}
let sq = (1..).find(|k| k * k > l).unwrap() - 1;
let mut dp = vec![0; sq + 1];
for (i, dp) in dp.iter_mut().enumerate().skip(1) {
*dp = l / (i * i);
}
enumerate_prime(sq, |p| {
if p > 3 {
for j in 1..=(sq / p) {
dp[j] -= dp[j * p];
}
}
});
dp[1]
};
let mut memo = vec![];
let mut d = 1usize;
while d <= l {
let mut x = d;
while x <= l {
let v = calc(l / x);
memo.push((x, v));
x *= 3;
}
d *= 2;
}
memo.sort();
for &p in [2, 3].iter() {
for i in 0..memo.len() {
let (x, _) = memo[i];
for j in (i + 1)..memo.len() {
if x * p == memo[j].0 {
memo[i].1 -= memo[j].1;
}
}
}
}
let mut dp = vec![false; memo.len()];
for a in a {
let pos = memo.iter().position(|p| p.0 == a).unwrap();
dp[pos] = true;
}
let mut ans = 0;
for i in 0..memo.len() {
if dp[i] {
ans += memo[i].1;
let v = memo[i].0;
for j in (i + 1)..memo.len() {
if memo[j].0 % v == 0 {
dp[j] ^= true;
}
}
}
}
println!("{}", ans);
}
fn test() {
let n = 1000;
let mut dp = vec![false; n + 1];
dp[1] = true;
dp[2] = true;
for i in 1..=n {
if dp[i] {
for j in 2..=(n / i) {
dp[j * i] ^= true;
}
if i % 2 == 0 {
println!("{} {} {}", i, i.trailing_zeros(), i / 4);
}
}
/*
let x = (2..).take_while(|&p| p * p <= i).any(|p| i % (p * p) == 0);
assert_eq!(!x, dp[i], "{}", i);
*/
}
}
// ---------- begin input macro ----------
// reference: https://qiita.com/tanakh/items/0ba42c7ca36cd29d0ac8
#[macro_export]
macro_rules! input {
(source = $s:expr, $($r:tt)*) => {
let mut iter = $s.split_whitespace();
input_inner!{iter, $($r)*}
};
($($r:tt)*) => {
let s = {
use std::io::Read;
let mut s = String::new();
std::io::stdin().read_to_string(&mut s).unwrap();
s
};
let mut iter = s.split_whitespace();
input_inner!{iter, $($r)*}
};
}
#[macro_export]
macro_rules! input_inner {
($iter:expr) => {};
($iter:expr, ) => {};
($iter:expr, $var:ident : $t:tt $($r:tt)*) => {
let $var = read_value!($iter, $t);
input_inner!{$iter $($r)*}
};
}
#[macro_export]
macro_rules! read_value {
($iter:expr, ( $($t:tt),* )) => {
( $(read_value!($iter, $t)),* )
};
($iter:expr, [ $t:tt ; $len:expr ]) => {
(0..$len).map(|_| read_value!($iter, $t)).collect::<Vec<_>>()
};
($iter:expr, chars) => {
read_value!($iter, String).chars().collect::<Vec<char>>()
};
($iter:expr, bytes) => {
read_value!($iter, String).bytes().collect::<Vec<u8>>()
};
($iter:expr, usize1) => {
read_value!($iter, usize) - 1
};
($iter:expr, $t:ty) => {
$iter.next().unwrap().parse::<$t>().expect("Parse error")
};
}
// ---------- end input macro ----------
// ---------- begin enumerate prime ----------
fn enumerate_prime<F>(n: usize, mut f: F)
where
F: FnMut(usize),
{
assert!(1 <= n && n <= 5 * 10usize.pow(8));
let batch = (n as f64).sqrt().ceil() as usize;
let mut is_prime = vec![true; batch + 1];
for i in (2..).take_while(|p| p * p <= batch) {
if is_prime[i] {
let mut j = i * i;
while let Some(p) = is_prime.get_mut(j) {
*p = false;
j += i;
}
}
}
let mut prime = vec![];
for (i, p) in is_prime.iter().enumerate().skip(2) {
if *p && i <= n {
f(i);
prime.push(i);
}
}
let mut l = batch + 1;
while l <= n {
let r = std::cmp::min(l + batch, n + 1);
is_prime.clear();
is_prime.resize(r - l, true);
for &p in prime.iter() {
let mut j = (l + p - 1) / p * p - l;
while let Some(is_prime) = is_prime.get_mut(j) {
*is_prime = false;
j += p;
}
}
for (i, _) in is_prime.iter().enumerate().filter(|p| *p.1) {
f(i + l);
}
l += batch;
}
}
// ---------- end enumerate prime ----------
akakimidori