Submission #620501

#TimeUsernameProblemLanguageResultExecution timeMemory
620501snasibov05Mechanical Doll (IOI18_doll)C++14
81.16 / 100
177 ms14732 KiB
#include "doll.h"
#include <queue>

using namespace std;

void create_circuit(int m, vector<int> a) {

    int n = a.size();
    vector<vector<int>> to(m+1);
    to[0].push_back(a[0]);
    for (int i = 0; i < n-1; ++i){
        to[a[i]].push_back(a[i+1]);
    }
    to[a[n-1]].push_back(0);

    vector<int> x, y;
    vector<bool> state;
    int cur = -1;
    vector<int> c(m+1);

    for (int i = 0; i <= m; ++i){
        int k = 0, b = 1;
        while (to[i].size() > b) b *= 2, k++;

        if (k == 0){
            if (to[i].empty()) c[i] = 0;
            else c[i] = to[i][0];
            continue;
        }

        int src = cur;
        int mx = cur - b + 2;
        c[i] = cur--;

        queue<int> q;
        q.push(cur+1);
        while (!q.empty()){
            state.push_back(true);
            int p = q.front();
            q.pop();
            if (cur < mx) {
                x.push_back(0);
                y.push_back(0);
                continue;
            }
            x.push_back(cur--);
            y.push_back(cur--);
            q.push(x.back());
            q.push(y.back());
        }

        int rem = b - (int)to[i].size();
        for (int j = 0; j < to[i].size() - rem; ++j){
            int pos = src;
            for (int l = 0; l < k-1; ++l) {
                if (state[-pos-1]) {
                    state[-pos-1] = false;
                    pos = x[-pos-1];
                } else{
                    state[-pos-1] = true;
                    pos = y[-pos-1];
                }
            }
            if (state[-pos-1]) {
                state[-pos-1] = false;
                x[-pos-1] = to[i][j];
            } else{
                state[-pos-1] = true;
                y[-pos-1] = to[i][j];
            }
        }

        for (int j = (int)to[i].size() - rem; j < to[i].size(); ++j){
            int pos = src;
            for (int l = 0; l < k-1; ++l) {
                if (state[-pos-1]) {
                    state[-pos-1] = false;
                    pos = x[-pos-1];
                } else{
                    state[-pos-1] = true;
                    pos = y[-pos-1];
                }
            }
            if (state[-pos-1]) {
                state[-pos-1] = false;
                x[-pos-1] = src;
            } else{
                state[-pos-1] = true;
                y[-pos-1] = src;
            }

            pos = src;
            for (int l = 0; l < k-1; ++l) {
                if (state[-pos-1]) {
                    state[-pos-1] = false;
                    pos = x[-pos-1];
                } else{
                    state[-pos-1] = true;
                    pos = y[-pos-1];
                }
            }
            if (state[-pos-1]) {
                state[-pos-1] = false;
                x[-pos-1] = to[i][j];
            } else{
                state[-pos-1] = true;
                y[-pos-1] = to[i][j];
            }
        }
    }

    while (true){


        vector<int> pr(-cur), tp(-cur);
        for (int i = cur + 1; i <= m; ++i){
            if (i < 0) {
                if (x[-i-1] < 0) pr[-x[-i-1]-1] = i, tp[-x[-i-1]-1] = 1;
                if (y[-i-1] < 0) pr[-y[-i-1]-1] = i, tp[-y[-i-1]-1] = 2;
            } else{
                if (c[i] < 0) pr[-c[i]-1] = i, tp[-c[i]-1] = 3;
            }
        }

        vector<bool> del(-cur);
        bool flag = false;
        for (int i = -1; i > cur; --i){
            if (x[-i-1] != y[-i-1]) continue;

            if (tp[-i-1] == 1) x[-pr[-i-1]-1] = x[-i-1];
            else if (tp[-i-1] == 2) y[-pr[-i-1]-1] = y[-i-1];
            else c[pr[-i-1]] = x[-i-1];

            del[-i-1] = true;
            flag = true;
        }

        if (!flag) break;

        vector<int> nname(-cur);
        int ncur = -1;
        for (int i = -1; i > cur; --i){
            if (del[-i-1]) continue;
            nname[-i-1] = ncur--;
        }

        vector<int> xx(-ncur), yy(-ncur);
        for (int i = -1; i > cur; --i){
            if (del[-i-1]) continue;
            if (x[-i-1] > 0) xx[-nname[-i-1]-1] = x[-i-1];
            else xx[-nname[-i-1]-1] = nname[-x[-i-1]-1];
            if (y[-i-1] > 0) yy[-nname[-i-1]-1] = y[-i-1];
            else yy[-nname[-i-1]-1] = nname[-y[-i-1]-1];
        }
        for (int i = 0; i <= m; ++i){
            if (c[i] > 0) continue;
            c[i] = nname[-c[i]-1];
        }

        x = xx, y = yy;
        cur = ncur;

    }

    answer(c, x, y);
}

Compilation message (stderr)

doll.cpp: In function 'void create_circuit(int, std::vector<int>)':
doll.cpp:23:29: warning: comparison of integer expressions of different signedness: 'std::vector<int>::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
   23 |         while (to[i].size() > b) b *= 2, k++;
      |                ~~~~~~~~~~~~~^~~
doll.cpp:39:17: warning: unused variable 'p' [-Wunused-variable]
   39 |             int p = q.front();
      |                 ^
doll.cpp:53:27: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   53 |         for (int j = 0; j < to[i].size() - rem; ++j){
      |                         ~~^~~~~~~~~~~~~~~~~~~~
doll.cpp:73:49: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   73 |         for (int j = (int)to[i].size() - rem; j < to[i].size(); ++j){
      |                                               ~~^~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...