CSES - NOI 2024 - Results
Submission details
Task:Chair Game
Sender:Erik Hedin
Submission time:2024-03-11 09:11:57 +0200
Language:C++17
Status:READY
Result:32
Feedback
groupverdictscore
#1ACCEPTED8
#20
#3ACCEPTED4
#40
#50
#60
#7ACCEPTED20
#80
Test results
testverdicttimegroup
#1ACCEPTED0.01 s1, 7, 8details
#2ACCEPTED0.01 s1, 7, 8details
#3ACCEPTED0.01 s1, 7, 8details
#4ACCEPTED0.01 s1, 7, 8details
#5ACCEPTED0.02 s1, 7, 8details
#6ACCEPTED0.01 s7, 8details
#7ACCEPTED0.10 s7, 8details
#8--2, 8details
#9ACCEPTED0.01 s3, 4, 5, 6, 8details
#10ACCEPTED0.02 s3, 4, 5, 6, 8details
#11ACCEPTED0.01 s3, 4, 5, 6, 8details
#12ACCEPTED0.18 s3, 4, 5, 6, 8details
#13ACCEPTED0.01 s4, 5, 6, 7, 8details
#14--4, 5, 6, 8details
#15--4, 5, 6, 8details
#16--4, 5, 6, 8details
#17ACCEPTED0.01 s5, 6, 7, 8details
#18ACCEPTED0.43 s5, 6, 8details
#19ACCEPTED0.01 s5, 6, 8details
#20--5, 6, 8details
#21ACCEPTED0.01 s1, 6, 7, 8details
#22ACCEPTED0.03 s6, 7, 8details
#23--6, 8details
#24--6, 8details
#25--8details
#26--8details
#27ACCEPTED0.07 s3, 4, 5, 6, 8details
#28ACCEPTED0.07 s8details
#29--8details
#30--8details

Code

#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <functional>
#include <set>
#include <map>
#include <queue>
#include <random>

using namespace std;

typedef long long int ll;
typedef vector<ll> vll;
typedef pair<ll, ll> pll;
typedef vector<pll> vpll;
typedef vector<vll> vvll;
typedef vector<bool> vb;
typedef vector<vb> vvb;
typedef set<pll> spll;

#define rep(i, a, b) for (ll i = a; i < b; i++)
#define sz(a) (ll) a.size()
#define mp(a, b) make_pair(a, b)
#define pb(a) push_back(a)
#define trav(itr, a, t) for (t::iterator itr = a.begin(); itr != a.end(); itr++)

mt19937 mt;

ll n;
vll s;

void solve() {
    cin >> n;
    s.resize(n);
    rep(i, 0, n) cin >> s[i];
    if (accumulate(s.begin(), s.end(), 0LL) % n) {
        cout << "NO\n";
        return;
    }

    deque<pll> DFS; // set chairs (pos, chair)
    while (sz(DFS) < n) {
        DFS.clear();

        vll chairs(s.begin(), s.end());
        // initialize b, c
        vll cnt(n + 1, 0); // how many of each chair is left
        vll options(n, 0); // how many chair types position can use
        vvb open(n, vb(n + 1, false));
        rep(i, 0, n) cnt[chairs[i]]++;
        rep(i, 0, n) rep(j, 1, n + 1) open[i][j] = cnt[j];
        rep(i, 0, n) rep(j, 1, n + 1) options[i] += open[i][j];

        set<pll> pq; // (options[i], i) for all i s.t. used[i] = false
        rep(i, 0, n) pq.insert(mp(options[i], i));

        shuffle(chairs.begin(), chairs.end(), mt);

        vb hit(n, false); // pos is arrival point
        vb used(n, false); // used

        for (ll t = 0; (t < 5 * n) && (sz(DFS) < n); t++) {
        //while (sz(DFS) < n) {
            pll nxt = *pq.begin();
            pq.erase(pq.begin());

            //cout << "nxt = (" << nxt.first << ", " << nxt.second << ")" << endl;

            /* trav(itr, pq, spll) {
                cout << "(" << itr->first << ", " << itr->second << ") ";
            }
            cout << endl; */

            if (nxt.first) {
                for (ll c = sz(chairs) - 1; c >= 0; c--) {
                    ll k = mt() % (c + 1); // pick random chair left

                    if (open[nxt.second][chairs[k]]) { // viable chair
                         // not already hit, add chair s[k] to nxt.second
                        //cout << "add (" << nxt.second << ", " << chairs[k] << ")" << endl;

                        used[nxt.second] = true;
                        hit[(nxt.second + chairs[k]) % n] = true;
                        DFS.pb(mp(nxt.second, chairs[k]));

                        // if s[k] is the last of it's type
                        if (--cnt[chairs[k]] == 0) {
                            rep(i, 0, n) {
                                if (open[i][chairs[k]] && !used[i]) {
                                    pq.erase(mp(options[i], i));
                                    options[i]--;
                                    open[i][chairs[k]] = false;
                                    pq.insert(mp(options[i], i));
                                }
                            }
                        }

                        // if certain chairs can hit the same pos as nxt.second
                        rep(j, 0, sz(chairs)) {
                            if (cnt[chairs[j]]) {
                                // (nxt.second + s[k] + n - s[j]) % n
                                ll oth = (nxt.second + chairs[k] + n -chairs[j]) % n;
                                if (open[oth][chairs[j]] && !used[oth]) {
                                    pq.erase(mp(options[oth], oth));
                                    options[oth]--;
                                    open[oth][chairs[j]] = false;
                                    pq.insert(mp(options[oth], oth));
                                }
                            }
                        }

                        swap(chairs[k], chairs.back());
                        chairs.pop_back();
                        c = 0;
                    } else {
                        swap(chairs[k], chairs[c]);
                    }
                }
            } else {
                pq.insert(nxt);
                // undo
                pll cur = DFS.back();
                pq.insert(mp(options[cur.first], cur.first));
                //cout << "remove (" << cur.first << ", " << cur.second << ")" << endl;
                DFS.pop_back();
                hit[(cur.first + cur.second) % n] = false;

                if (cnt[cur.second]++ == 0) {
                    rep(i, 0, n) {
                        if (!hit[(i + cur.second) % n] && !used[i]) {
                            pq.erase(mp(options[i], i));
                            options[i]++;
                            open[i][cur.second] = true;
                            pq.insert(mp(options[i], i));
                        }
                    }
                }

                rep(j, 0, sz(chairs)) {
                    if (cnt[chairs[j]]) {
                        ll oth = (cur.first + cur.second + n - chairs[j]) % n;
                        if (!open[oth][chairs[j]] && !used[oth]) {
                            pq.erase(mp(options[oth], oth));
                            options[oth]++;
                            open[oth][chairs[j]] = true;
                            pq.insert(mp(options[oth], oth));
                        }
                    }
                }

                used[cur.first] = false;
                chairs.pb(cur.second);
            }
        }
    }

    vll answ(n);
    rep(i, 0, n) {
        answ[DFS.front().first] = DFS.front().second;
        DFS.pop_front();
    }
    cout << "YES\n";
    rep(i, 0, n) cout << answ[i] << " ";
    cout << "\n";
}

int main() {
    cin.tie(NULL)->sync_with_stdio(false);

    random_device rd;
    //mt.seed(rd());
    mt.seed(0);

    ll testcases;
    cin >> testcases;
    rep(testcase, 0, testcases) {
        solve();
        cout << flush;
    }


    return 0;
}

/*
each position has a number of viable chairs

each time we add a chair:
 - we remove this option from ALL empty positions
 - we remove options for all positions which 'looks' at the now already hit position

each position keeps track of possible chairs to add.
on average, half of the chair types left should work

*/

Test details

Test 1

Group: 1, 7, 8

Verdict: ACCEPTED

input
637
1
1
2
1 1
...

correct output
YES

YES
1 1 
YES
...

user output
YES

YES
1 1 
YES
...
Truncated

Test 2

Group: 1, 7, 8

Verdict: ACCEPTED

input
246
7
1 1 1 1 1 1 1
7
1 1 2 1 1 7 1
...

correct output
YES
1 1 1 1 1 1 1 
YES
1 1 1 1 2 7 1 
YES
...

user output
YES
1 1 1 1 1 1 1 
YES
1 1 1 2 7 1 1 
YES
...
Truncated

Test 3

Group: 1, 7, 8

Verdict: ACCEPTED

input
810
8
1 1 1 1 1 1 1 1
8
1 1 1 8 1 1 2 1
...

correct output
YES
1 1 1 1 1 1 1 1 
YES
1 1 2 8 1 1 1 1 
YES
...

user output
YES
1 1 1 1 1 1 1 1 
YES
2 8 1 1 1 1 1 1 
YES
...
Truncated

Test 4

Group: 1, 7, 8

Verdict: ACCEPTED

input
1000
8
8 8 5 2 8 7 6 5
8
6 5 2 2 8 2 1 6
...

correct output
NO
YES
8 2 2 6 2 5 1 6 
NO
NO
...

user output
NO
YES
2 5 2 6 1 6 2 8 
NO
NO
...
Truncated

Test 5

Group: 1, 7, 8

Verdict: ACCEPTED

input
1000
8
2 1 7 7 2 3 8 2
8
4 1 5 4 7 3 5 3
...

correct output
YES
7 2 2 7 1 3 8 2 
YES
4 4 7 3 3 5 5 1 
YES
...

user output
YES
7 2 8 1 2 3 7 2 
YES
5 3 4 5 7 4 1 3 
YES
...
Truncated

Test 6

Group: 7, 8

Verdict: ACCEPTED

input
1000
16
15 16 6 4 14 2 1 6 2 16 10 2 9...

correct output
NO
NO
NO
NO
NO
...

user output
NO
NO
NO
NO
NO
...
Truncated

Test 7

Group: 7, 8

Verdict: ACCEPTED

input
1000
16
2 4 13 6 8 16 12 8 16 5 9 5 9 ...

correct output
YES
13 5 2 8 12 2 8 5 16 16 9 6 9 ...

user output
YES
6 8 2 16 13 9 12 5 2 4 5 16 9 ...
Truncated

Test 8

Group: 2, 8

Verdict:

input
1000
1
1
2
1 2
...

correct output
YES

NO
YES
3 1 2 
...

user output
(empty)

Test 9

Group: 3, 4, 5, 6, 8

Verdict: ACCEPTED

input
988
1
1
2
1 1
...

correct output
YES

YES
1 1 
YES
...

user output
YES

YES
1 1 
YES
...
Truncated

Test 10

Group: 3, 4, 5, 6, 8

Verdict: ACCEPTED

input
199
1
1
2
1 1
...

correct output
YES

YES
1 1 
YES
...

user output
YES

YES
1 1 
YES
...
Truncated

Test 11

Group: 3, 4, 5, 6, 8

Verdict: ACCEPTED

input
1000
100
1 1 1 2 1 1 2 2 1 1 1 1 1 2 1 ...

correct output
NO
NO
NO
NO
NO
...

user output
NO
NO
NO
NO
NO
...
Truncated

Test 12

Group: 3, 4, 5, 6, 8

Verdict: ACCEPTED

input
1000
100
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ...

correct output
YES
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ...

user output
YES
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ...
Truncated

Test 13

Group: 4, 5, 6, 7, 8

Verdict: ACCEPTED

input
963
1
1
2
1 1
...

correct output
YES

YES
1 1 
YES
...

user output
YES

YES
1 1 
YES
...
Truncated

Test 14

Group: 4, 5, 6, 8

Verdict:

input
979
1
1
2
1 1
...

correct output
YES

YES
1 1 
YES
...

user output
(empty)

Test 15

Group: 4, 5, 6, 8

Verdict:

input
1000
100
3 3 1 2 1 1 2 3 1 3 2 1 1 3 1 ...

correct output
NO
NO
NO
NO
NO
...

user output
(empty)

Test 16

Group: 4, 5, 6, 8

Verdict:

input
1000
100
1 2 2 2 2 1 1 1 2 3 1 1 3 2 1 ...

correct output
YES
2 2 2 3 1 2 3 1 2 3 1 3 1 3 1 ...

user output
(empty)

Test 17

Group: 5, 6, 7, 8

Verdict: ACCEPTED

input
980
1
1
2
1 1
...

correct output
YES

YES
1 1 
YES
...

user output
YES

YES
1 1 
YES
...
Truncated

Test 18

Group: 5, 6, 8

Verdict: ACCEPTED

input
947
1
1
2
1 1
...

correct output
YES

YES
1 1 
YES
...

user output
YES

YES
1 1 
YES
...
Truncated

Test 19

Group: 5, 6, 8

Verdict: ACCEPTED

input
1000
100
1 2 4 2 1 3 1 2 2 3 1 1 3 1 4 ...

correct output
NO
NO
NO
NO
NO
...

user output
NO
NO
NO
NO
NO
...
Truncated

Test 20

Group: 5, 6, 8

Verdict:

input
1000
100
3 4 4 4 4 4 4 3 3 3 4 4 2 3 3 ...

correct output
YES
4 2 4 4 1 3 4 2 4 2 3 4 2 4 4 ...

user output
(empty)

Test 21

Group: 1, 6, 7, 8

Verdict: ACCEPTED

input
715
1
1
2
1 1
...

correct output
YES

YES
1 1 
YES
...

user output
YES

YES
1 1 
YES
...
Truncated

Test 22

Group: 6, 7, 8

Verdict: ACCEPTED

input
843
1
1
2
1 1
...

correct output
YES

YES
1 1 
YES
...

user output
YES

YES
1 1 
YES
...
Truncated

Test 23

Group: 6, 8

Verdict:

input
1000
100
3 4 5 1 4 4 2 3 2 3 4 1 1 1 2 ...

correct output
NO
NO
NO
NO
NO
...

user output
(empty)

Test 24

Group: 6, 8

Verdict:

input
1000
100
5 3 4 3 5 3 3 5 5 4 5 5 5 5 2 ...

correct output
YES
4 4 5 5 2 4 4 5 3 5 5 2 5 5 2 ...

user output
(empty)

Test 25

Group: 8

Verdict:

input
1000
100
88 70 59 44 28 10 19 19 42 16 ...

correct output
NO
NO
NO
NO
NO
...

user output
(empty)

Test 26

Group: 8

Verdict:

input
1000
100
31 72 52 30 77 56 79 10 88 11 ...

correct output
YES
31 62 14 10 66 63 1 82 37 92 3...

user output
(empty)

Test 27

Group: 3, 4, 5, 6, 8

Verdict: ACCEPTED

input
1000
1
1
2
1 1
...

correct output
YES

YES
1 1 
YES
...

user output
YES

YES
1 1 
YES
...
Truncated

Test 28

Group: 8

Verdict: ACCEPTED

input
1000
1
1
2
2 2
...

correct output
YES

YES
2 2 
YES
...

user output
YES

YES
2 2 
YES
...
Truncated

Test 29

Group: 8

Verdict:

input
1000
100
87 81 29 35 8 98 77 50 46 34 5...

correct output
YES
34 74 25 91 80 18 95 26 88 12 ...

user output
(empty)

Test 30

Group: 8

Verdict:

input
1000
100
65 92 39 22 67 41 17 65 97 71 ...

correct output
YES
9 38 24 59 69 24 63 3 22 35 24...

user output
(empty)