Files
contests/atcoder/beginner_contests/abc050/src/bin/c.rs
2023-04-28 17:06:07 +02:00

60 lines
1.8 KiB
Rust

use std::collections::HashMap;
use proconio::input;
const MAX_RESULT: u64 = 1000000007;
fn calc_orders(ans: &[u64]) -> u64 {
let mut visited_positions: HashMap<u64, usize> = HashMap::new();
let mut result = 1;
let l = ans.len();
// For all reports, it needs to be at least 0 and at most n - 1.
if l % 2 == 0 {
for &a in ans.into_iter() {
// In this case, all reports have to be odd and occur twice.
// We don't have to check if a < 0 because a is unsigned and rust will panic during the
// parsing of the input anyways.
if a % 2 != 1 || a >= l as u64 {
return 0;
}
let number_of_reports = *visited_positions.get(&a).unwrap_or(&0);
if number_of_reports > 1 {
return 0;
} else if number_of_reports == 0 {
result = (result * 2) % MAX_RESULT;
}
visited_positions.insert(a, number_of_reports + 1);
}
} else if l % 2 == 1 {
// In this case, all reports have to be even, occur twice, except 0, which needs to occur
// exactly once.
for &a in ans.into_iter() {
if a % 2 != 0 || a >= l as u64 {
return 0;
}
let number_of_reports = *visited_positions.get(&a).unwrap_or(&0);
if number_of_reports > 1 || (number_of_reports > 0 && a == 0) {
return 0;
} else if a != 0 && number_of_reports == 0 {
result = (result * 2) % MAX_RESULT;
}
visited_positions.insert(a, number_of_reports + 1);
}
}
return result;
}
fn main() {
input! {
n: usize,
ans: [u64; n],
};
println!("{}", calc_orders(&ans));
}