CSES - Putka Open 2020 – 4/5 - Results
Submission details
Task:Neliöt
Sender:Hennkka
Submission time:2020-11-06 21:16:13 +0200
Language:Rust
Status:READY
Result:100
Feedback
groupverdictscore
#1ACCEPTED28
#2ACCEPTED72
Test results
testverdicttimegroup
#1ACCEPTED0.01 s1, 2details
#2ACCEPTED0.01 s1, 2details
#3ACCEPTED0.01 s2details

Compiler report

warning: unused variable: `j`
  --> input/code.rs:21:9
   |
21 |     for j in (0..).map(|j| 1 << j).take_while(|j| *j < even) {
   |         ^ help: consider prefixing with an underscore: `_j`
   |
   = note: `#[warn(unused_variables)]` on by default

warning: unused variable: `i`
  --> input/code.rs:82:21
   |
82 |                 for i in (0..).take_while(|i| *i * *i <= n) {
   |                     ^ help: consider prefixing with an underscore: `_i`

Code

use rand::prelude::*;
use std::collections::BTreeMap;
use std::io::BufRead;
fn powmod(b: u64, e: u64, m: u64) -> u64 {
if e == 0 {
1
} else if e % 2 == 0 {
let p = powmod(b, e / 2, m) as u128;
((p * p) % m as u128) as u64
} else {
((b as u128 * powmod(b, e - 1, m) as u128) % m as u128) as u64
}
}
fn is_w(a: u64, even: u64, odd: u64, p: u64) -> bool {
let mut u = powmod(a, odd, p);
if u == 1 {
return false;
}
for j in (0..).map(|j| 1 << j).take_while(|j| *j < even) {
if u == p - 1 {
return false;
}
u = ((u as u128 * u as u128) % p as u128) as u64;
}
true
}
fn is_prime(p: u64) -> bool {
if p == 2 {
true
} else if p <= 1 || p % 2 == 0 {
false
} else {
let mut odd = p - 1;
let mut even = 1;
while odd % 2 == 0 {
even *= 2;
odd /= 2;
}
for b in &[2, 325, 9375, 28178, 450775, 9780504, 1795265022] {
let a = b % p;
if a == 0 {
return true;
}
if is_w(a, even, odd, p) {
return false;
}
}
true
}
}
pub fn gcd(a: u64, b: u64) -> u64 {
if b == 0 {
a
} else {
gcd(b, a % b)
}
}
fn factor(n: u64) -> BTreeMap<u64, usize> {
fn step(x: &mut u64, n: u64, c: u64) {
*x = ((*x as u128 * *x as u128 + c as u128) % n as u128) as u64;
}
fn f(n: u64, r: &mut BTreeMap<u64, usize>) {
let mut n = n;
while n % 2 == 0 {
n /= 2;
*r.entry(2).or_insert(0) += 1;
}
if n == 1 {
} else if is_prime(n) {
*r.entry(n).or_insert(0) += 1;
} else {
loop {
let mut x = thread_rng().next_u64() % n;
let mut y = x;
let c = thread_rng().next_u64() % n;
for i in (0..).take_while(|i| *i * *i <= n) {
step(&mut x, n, c);
step(&mut x, n, c);
step(&mut y, n, c);
let g = gcd(x.max(y) - x.min(y), n);
if g == n {
break;
} else if g > 1 {
f(n / g, r);
f(g, r);
return;
}
}
}
}
}
let mut res = BTreeMap::new();
if n > 1 {
f(n, &mut res);
}
res
}
fn solve(c: usize) -> bool {
for (p, k) in factor(c as u64) {
if p % 4 == 3 && k % 2 == 1 {
return false;
}
}
true
}
fn main() {
let stdin = std::io::stdin();
let stdin = stdin.lock();
let mut lines = stdin.lines();
let t: usize = lines.next().unwrap().unwrap().parse().unwrap();
for _ in 0..t {
let c: usize = lines.next().unwrap().unwrap().parse().unwrap();
if solve(c) {
println!("YES");
} else {
println!("NO");
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_prime() {
assert!(is_prime(2));
assert!(is_prime(3));
assert!(is_prime(5));
assert!(is_prime(7));
assert!(is_prime(11));
assert!(is_prime(13));
assert!(is_prime(1_000_000_007));
assert!(is_prime(1_000_000_009));
assert!(!is_prime(14));
assert!(!is_prime(15));
assert!(!is_prime(1_000_000_007 * 1_000_000_009));
}
#[test]
fn test_factor() {
assert_eq!(factor(16), [(2, 4)].into_iter().copied().collect());
assert_eq!(factor(15), [(3, 1), (5, 1)].into_iter().copied().collect());
assert_eq!(
factor(1_000_000_007 * 1_000_000_009),
[(1_000_000_007, 1), (1_000_000_009, 1)]
.into_iter()
.copied()
.collect()
);
}
}

Test details

Test 1

Group: 1, 2

Verdict: ACCEPTED

input
100
1
2
3
4
...

correct output
YES
YES
NO
YES
YES
...

user output
YES
YES
NO
YES
YES
...
Truncated

Test 2

Group: 1, 2

Verdict: ACCEPTED

input
100
522
419
402
969
...

correct output
YES
NO
NO
NO
NO
...

user output
YES
NO
NO
NO
NO
...
Truncated

Test 3

Group: 2

Verdict: ACCEPTED

input
100
575833539
744851460
436154655
655319365
...

correct output
NO
NO
NO
NO
NO
...

user output
NO
NO
NO
NO
NO
...
Truncated