CSES - Putka Open 2020 – 2/5 - Results
Submission details
Task:Planeetat
Sender:Hennkka
Submission time:2020-09-27 12:18:17 +0300
Language:Rust
Status:READY
Result:24
Feedback
groupverdictscore
#1ACCEPTED24
#20
#30
Test results
testverdicttimegroup
#1ACCEPTED0.01 s1, 2, 3details
#2ACCEPTED0.01 s1, 2, 3details
#3ACCEPTED0.01 s1, 2, 3details
#4ACCEPTED0.01 s1, 2, 3details
#5ACCEPTED0.01 s1, 2, 3details
#6ACCEPTED0.01 s1, 2, 3details
#7ACCEPTED0.01 s1, 2, 3details
#8ACCEPTED0.01 s1, 2, 3details
#9ACCEPTED0.01 s1, 2, 3details
#10ACCEPTED0.01 s1, 2, 3details
#110.01 s2, 3details
#120.01 s2, 3details
#130.01 s2, 3details
#140.01 s3details
#150.01 s3details
#160.01 s3details
#170.01 s3details
#180.01 s3details
#190.01 s3details
#200.01 s3details
#210.01 s3details
#220.01 s3details
#230.01 s3details
#240.01 s3details
#250.01 s3details

Compiler report

warning: unused import: `std::collections::BTreeSet`
 --> input/code.rs:1:5
  |
1 | use std::collections::BTreeSet;
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: `#[warn(unused_imports)]` on by default

warning: unused import: `std::collections::VecDeque`
 --> input/code.rs:2:5
  |
2 | use std::collections::VecDeque;
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^

warning: function is never used: `print_iter`
 --> input/code.rs:7:4
  |
7 | fn print_iter<I: Iterator>(iter: I)
  |    ^^^^^^^^^^
  |
  = note: `#[warn(dead_code)]` on by default

warning: struct is never constructed: `UnionFind`
  --> input/code.rs:21:8
   |
21 | struct UnionFind {
   |        ^^^^^^^^^

warning: method is never used: `new`
  --> input/code.rs:26:5
   |
26 |     pub fn new(n: usize) -> Self {
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

warning: method is never used: `find`
  --> input/code.rs:32:5
   |
32 |     pub fn find(&mut self, n: usize) -> usize {
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

warning: method...

Code

use std::collections::BTreeSet;
use std::collections::VecDeque;
use std::io::BufRead;

const MOD: usize = 1_000_000_007;

fn print_iter<I: Iterator>(iter: I)
where
    <I as Iterator>::Item: std::fmt::Display,
{
    let mut iter = iter;
    if let Some(v) = iter.next() {
        print!("{}", v);
        for v in iter {
            print!(" {}", v);
        }
    }
    println!();
}

struct UnionFind {
    links: Vec<usize>,
}

impl UnionFind {
    pub fn new(n: usize) -> Self {
        Self {
            links: (0..n).collect(),
        }
    }

    pub fn find(&mut self, n: usize) -> usize {
        if self.links[n] == n {
            n
        } else {
            self.links[n] = self.find(self.links[n]);
            self.links[n]
        }
    }

    pub fn union(&mut self, a: usize, b: usize) {
        let a = self.find(a);
        let b = self.find(b);
        self.links[a] = b;
    }
}

/// Compute the number of ways in which n planets can belong to 1 component
fn component_count(n: usize) -> usize {
    if n == 1 {
        1
    } else {
        let n1 = component_count(n - 1);
        let mut res = 0;
        // We can add planet n as the last one in the chain and have it point at any of the n planets
        res += n * n1;
        // We can also have the planet just point to any one of the planets already in the set
        res += (n - 1) * n1;
        // We can also replace any of the existing edges with the new node
        res += n - 1;
        res
    }
}

fn factorial(n: usize) -> usize {
    if n == 0 {
        1
    } else {
        n * factorial(n - 1)
    }
}

fn binomial(k: usize, n: usize) -> usize {
    factorial(n) / (factorial(k) * factorial(n - k))
}

fn next_configuration(conf: &mut [usize]) -> bool {
    let n = conf.len();
    for i in 0..n {
        if conf[i] != n - 1 {
            conf[i] += 1;
            return false;
        } else {
            conf[i] = 0;
        }
    }
    true
}

fn brute(n: usize) -> Vec<usize> {
    let mut res = vec![0; n];
    let mut conf = vec![0; n];

    // fn find_component(i: usize, conf: &[usize]) -> usize {
    //     if conf[i] == i {
    //         i
    //     } else {
    //         find_component(conf[i], conf)
    //     }
    // }

    let mut last = 0;
    loop {
        if conf[n - 2] == last {
            println!("{}, {}", last, conf[n - 1]);
            last = (last + 1) % n;
        }
        // Count components in conf
        let mut components = UnionFind::new(n);
        for i in 0..n {
            components.union(i, conf[i]);
        }
        let mut component_list = Vec::new();
        for i in 0..n {
            component_list.push(components.find(i));
        }
        component_list.sort();
        component_list.dedup();
        res[n - component_list.len()] += 1;

        if next_configuration(&mut conf) {
            break;
        }
    }

    res
}

// n planets, of which k are not used, subset has at most max_s elements, there are already parts subsets
fn subsolve(n: usize, k: usize, max_s: usize, mul: usize, parts: usize, res: &mut [usize]) {
    assert!(max_s >= 1);
    if k == 0 {
        // No planets left.
        res[parts - 1] += mul;
        return;
    }

    // Try all possible sizes for the next subset
    for s in 1..=max_s {
        if k < s {
            break;
        }
        subsolve(
            n,
            k - s,
            s,
            mul * binomial(s, k) * component_count(s),
            parts + 1,
            res,
        );
    }

    // todo!()
}

fn presolved(n: usize) -> Vec<usize> {
    match n {
        1 => vec![1],
        2 => vec![1, 3],
        3 => vec![1, 9, 17],
        4 => vec![1, 18, 95, 142],
        5 => vec![1, 30, 305, 1220, 1569],
        6 => vec![1, 45, 745, 5595, 18694, 21576],
        7 => vec![1, 63, 1540, 18515, 113974, 334369, 355081],
        8 => vec![1, 84, 2842, 49840, 484729, 2581964, 6852460, 6805296],
        9 => vec![
            1, 108, 4830, 116172, 1632099, 13591116, 64727522, 158479488, 148869153,
        ]
        .into_iter()
        .map(|v| v % MOD)
        .collect(),
        10 => vec![
            1, 135, 7710, 243390, 4654713, 55545735, 409987640, 1783995060, 4085349936, 3660215680,
        ]
        .into_iter()
        .map(|v| v % MOD)
        .collect(),
        _ => unimplemented!(),
    }
}

fn solve(n: usize) -> Vec<usize> {
    // let mut res = vec![0; n];
    // subsolve(n, n, n, 1, 0, &mut res);
    // res
    // brute(n)
    presolved(n)
}

fn main() {
    let stdin = std::io::stdin();
    let stdin = stdin.lock();
    let mut lines = stdin.lines();
    let n: usize = lines.next().unwrap().unwrap().parse().unwrap();
    for v in solve(n).into_iter().rev() {
        println!("{}", v);
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_component_count() {
        assert_eq!(component_count(1), 1);
        assert_eq!(component_count(2), 3);
        assert_eq!(component_count(3), 17);
        assert_eq!(component_count(4), 142);
        assert_eq!(component_count(5), 1569);
        assert_eq!(component_count(6), 21576);
    }

    #[test]
    fn test_samples() {
        assert_eq!(solve(1), vec![1]);
        assert_eq!(solve(2), vec![1, 3]);
        assert_eq!(solve(3), vec![1, 9, 17]);
        assert_eq!(solve(4), vec![1, 18, 95, 142]);
        assert_eq!(solve(5), vec![1, 30, 305, 1220, 1569]);
        assert_eq!(solve(6), vec![1, 45, 745, 5595, 18694, 21576]);
        assert_eq!(solve(7), vec![1, 63, 1540, 18515, 113974, 334369, 355081]);
        assert_eq!(
            solve(8),
            vec![1, 84, 2842, 49840, 484729, 2581964, 6852460, 6805296]
        );
        assert_eq!(
            solve(9),
            vec![1, 108, 4830, 116172, 1632099, 13591116, 64727522, 158479488, 148869153]
                .into_iter()
                .map(|v| v % MOD)
        );
        assert_eq!(
            solve(10),
            vec![
                1, 135, 7710, 243390, 4654713, 55545735, 409987640, 1783995060, 4085349936,
                3660215680
            ]
            .into_iter()
            .map(|v| v % MOD)
        );
    }
}

Test details

Test 1

Group: 1, 2, 3

Verdict: ACCEPTED

input
1

correct output
1

user output
1

Test 2

Group: 1, 2, 3

Verdict: ACCEPTED

input
2

correct output
3
1

user output
3
1

Test 3

Group: 1, 2, 3

Verdict: ACCEPTED

input
3

correct output
17
9
1

user output
17
9
1

Test 4

Group: 1, 2, 3

Verdict: ACCEPTED

input
4

correct output
142
95
18
1

user output
142
95
18
1

Test 5

Group: 1, 2, 3

Verdict: ACCEPTED

input
5

correct output
1569
1220
305
30
1

user output
1569
1220
305
30
1

Test 6

Group: 1, 2, 3

Verdict: ACCEPTED

input
6

correct output
21576
18694
5595
745
45
...

user output
21576
18694
5595
745
45
...

Test 7

Group: 1, 2, 3

Verdict: ACCEPTED

input
7

correct output
355081
334369
113974
18515
1540
...

user output
355081
334369
113974
18515
1540
...

Test 8

Group: 1, 2, 3

Verdict: ACCEPTED

input
8

correct output
6805296
6852460
2581964
484729
49840
...

user output
6805296
6852460
2581964
484729
49840
...

Test 9

Group: 1, 2, 3

Verdict: ACCEPTED

input
9

correct output
148869153
158479488
64727522
13591116
1632099
...

user output
148869153
158479488
64727522
13591116
1632099
...

Test 10

Group: 1, 2, 3

Verdict: ACCEPTED

input
10

correct output
660215659
85349908
783995053
409987640
55545735
...

user output
660215659
85349908
783995053
409987640
55545735
...

Test 11

Group: 2, 3

Verdict:

input
20

correct output
8033007
474885151
998010619
720259168
345757330
...

user output
(empty)

Error:
thread 'main' panicked at 'not implemented', input/code.rs:178:14
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Test 12

Group: 2, 3

Verdict:

input
50

correct output
637699856
613177596
194234103
50828885
988168359
...

user output
(empty)

Error:
thread 'main' panicked at 'not implemented', input/code.rs:178:14
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Test 13

Group: 2, 3

Verdict:

input
100

correct output
894456323
406549429
962038245
430640330
61348310
...

user output
(empty)

Error:
thread 'main' panicked at 'not implemented', input/code.rs:178:14
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Test 14

Group: 3

Verdict:

input
666

correct output
189730587
968711879
553374698
53051125
139917248
...

user output
(empty)

Error:
thread 'main' panicked at 'not implemented', input/code.rs:178:14
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Test 15

Group: 3

Verdict:

input
3333

correct output
79235821
455292218
627100211
591681254
695866885
...

user output
(empty)

Error:
thread 'main' panicked at 'not implemented', input/code.rs:178:14
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Test 16

Group: 3

Verdict:

input
4991

correct output
482116496
245260697
151422537
180441123
318466624
...

user output
(empty)

Error:
thread 'main' panicked at 'not implemented', input/code.rs:178:14
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Test 17

Group: 3

Verdict:

input
4992

correct output
141010647
787351178
684701591
872974815
631476284
...

user output
(empty)

Error:
thread 'main' panicked at 'not implemented', input/code.rs:178:14
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Test 18

Group: 3

Verdict:

input
4993

correct output
504034249
588971460
281533415
928250892
416697844
...

user output
(empty)

Error:
thread 'main' panicked at 'not implemented', input/code.rs:178:14
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Test 19

Group: 3

Verdict:

input
4994

correct output
266134603
90079109
544661648
812099750
17249410
...

user output
(empty)

Error:
thread 'main' panicked at 'not implemented', input/code.rs:178:14
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Test 20

Group: 3

Verdict:

input
4995

correct output
833898560
663839791
109127071
321675160
86285359
...

user output
(empty)

Error:
thread 'main' panicked at 'not implemented', input/code.rs:178:14
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Test 21

Group: 3

Verdict:

input
4996

correct output
721158645
167929822
115103278
491345159
114397872
...

user output
(empty)

Error:
thread 'main' panicked at 'not implemented', input/code.rs:178:14
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Test 22

Group: 3

Verdict:

input
4997

correct output
691405606
436947443
82656395
514529009
783319673
...

user output
(empty)

Error:
thread 'main' panicked at 'not implemented', input/code.rs:178:14
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Test 23

Group: 3

Verdict:

input
4998

correct output
829675470
688714502
189351950
956110193
20883331
...

user output
(empty)

Error:
thread 'main' panicked at 'not implemented', input/code.rs:178:14
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Test 24

Group: 3

Verdict:

input
4999

correct output
343936737
47032567
190931571
827280581
160866637
...

user output
(empty)

Error:
thread 'main' panicked at 'not implemented', input/code.rs:178:14
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Test 25

Group: 3

Verdict:

input
5000

correct output
364064601
633559852
352848841
666954216
428009512
...

user output
(empty)

Error:
thread 'main' panicked at 'not implemented', input/code.rs:178:14
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace