Submission #688556

# Submission time Handle Problem Language Result Execution time Memory
688556 2023-01-27T17:34:42 Z nhphucqt ICC (CEOI16_icc) C++17
100 / 100
118 ms 504 KB
#include <bits/stdc++.h>
#include "icc.h"

using namespace std;

const int N = 107;
int fa[N];
int nTotal, nLef, nRig;
int total[N], lef[N], rig[N];
int tnLef, tnRig;
int tmpLef[N], tmpRig[N];
vector<int> comp[N];

int root (int x) {
    return fa[x] < 0 ? x : fa[x] = root(fa[x]);
}

void unite(int u, int v) {
    u = root(u);
    v = root(v);
    assert(u != v);
    if (fa[u] > fa[v]) {
        swap(u, v);
    }
    fa[u] += fa[v];
    fa[v] = u;
    for (int x : comp[v]) {
        comp[u].push_back(x);
    }
}

void arrCopy(int sizA, int A[], int &sizB, int B[]) {
    for (int i = 0; i < sizA; ++i) {
        B[i] = A[i];
    }
    sizB = sizA;
}

void divide(int sizA, int A[], int &sizB, int B[], int &sizC, int C[]) {
    sizB = sizC = 0;
    for (int i = 0; i < sizA/2; ++i) {
        B[sizB++] = A[i];
    }
    for (int i = sizA/2; i < sizA; ++i) {
        C[sizC++] = A[i];
    }
}

void makeQuery2() {
    while (nLef > 1 || nRig > 1) {
        tnLef = tnRig = 0;
        for (int i = (nLef+1)/2; i < nLef; ++i) {
            tmpLef[tnLef++] = lef[i];
        }
        for (int i = (nRig+1)/2; i < nRig; ++i) {
            tmpRig[tnRig++] = rig[i];
        }
        nLef = (nLef+1)/2;
        nRig = (nRig+1)/2;
        if (query(nLef, tnRig, lef, tmpRig) == 1) {
            arrCopy(tnRig, tmpRig, nRig, rig);
        } else if (query(tnLef, nRig, tmpLef, rig) == 1) {
            arrCopy(tnLef, tmpLef, nLef, lef);
        } else if (query(tnLef, tnRig, tmpLef, tmpRig) == 1) {
            arrCopy(tnLef, tmpLef, nLef, lef);
            arrCopy(tnRig, tmpRig, nRig, rig);
        }
        // cerr << "Make query: " << query(nLef, nRig, lef, rig) << '\n';
    }
}

void makeQuery() {
    while (nLef > 1) {
        if (query((nLef+1)/2, nRig, lef, rig) == 1) {
            nLef = (nLef+1)/2;
        } else {
            int cLef = 0;
            for (int i = (nLef+1)/2; i < nLef; ++i) {
                lef[cLef++] = lef[i];
            }
            nLef = cLef;
        }
    }
    while (nRig > 1) {
        if (query(nLef, (nRig+1)/2, lef, rig) == 1) {
            nRig = (nRig+1)/2;
        } else {
            int cRig = 0;
            for (int i = (nRig+1)/2; i < nRig; ++i) {
                rig[cRig++] = rig[i];
            }
            nRig = cRig;
        }
    }
}

void run(int numNode) {
    cerr << numNode << '\n';
    memset(fa, -1, (numNode+1) * sizeof(int));
    for (int i = 1; i <= numNode; ++i) {
        comp[i].push_back(i);
    }
    int numComp = numNode;
    while (numComp-- > 1) {
        cerr << "Num Comp: " << numComp << '\n';
        nTotal = 0;
        for (int i = 1; i <= numNode; ++i) {
            // cerr << " >> " << i << '\n';
            if (i == root(i)) {
                total[nTotal++] = i;
            }
        }
        // cerr << "Total : ";
        // for (int i = 0; i < nTotal; ++i) {
        //     cerr << total[i] << ' ';
        // } cerr << '\n';
        for (int j = 0; j < 7; ++j) {
            nLef = nRig = 0;
            for (int i = 0; i < nTotal; ++i) {
                if ((i>>j) & 1) {
                    for (int x : comp[total[i]]) {
                        lef[nLef++] = x;
                    }
                } else {
                    for (int x : comp[total[i]]) {
                        rig[nRig++] = x;
                    }
                }
            }
            // cerr << "lef: ";
            // for (int i = 0; i < nLef; ++i) {
            //     cerr << lef[i] << ' ';
            // }
            // cerr << '\n';
            // cerr << "rig: ";
            // for (int i = 0; i < nRig; ++i) {
            //     cerr << rig[i] << ' ';
            // }
            // cerr << '\n';
            if (31 - __builtin_clz(nTotal-1) == j) {
                break;
            }
            if (query(nLef, nRig, lef, rig) == 1) {
                break;
            }
            // cerr << "---\n";
        }

        // cerr << "First term: " << query(nLef, nRig, lef, rig) << '\n';

        makeQuery();

        assert(nLef == 1 && nRig == 1);

        // cerr << query(nLef, nRig, lef, rig) << '\n';
        
        // cerr << "Set road: " << lef[0] << ' ' << rig[0] << '\n';
        setRoad(lef[0], rig[0]);
        unite(lef[0], rig[0]);
    }
}
# Verdict Execution time Memory Grader output
1 Correct 5 ms 468 KB Ok! 98 queries used.
2 Correct 5 ms 468 KB Ok! 96 queries used.
# Verdict Execution time Memory Grader output
1 Correct 29 ms 468 KB Ok! 534 queries used.
2 Correct 33 ms 468 KB Ok! 616 queries used.
3 Correct 33 ms 468 KB Ok! 606 queries used.
# Verdict Execution time Memory Grader output
1 Correct 105 ms 468 KB Ok! 1430 queries used.
2 Correct 105 ms 496 KB Ok! 1513 queries used.
3 Correct 110 ms 468 KB Ok! 1589 queries used.
4 Correct 109 ms 488 KB Ok! 1468 queries used.
# Verdict Execution time Memory Grader output
1 Correct 104 ms 488 KB Ok! 1503 queries used.
2 Correct 114 ms 492 KB Ok! 1492 queries used.
3 Correct 106 ms 492 KB Ok! 1537 queries used.
4 Correct 108 ms 468 KB Ok! 1494 queries used.
# Verdict Execution time Memory Grader output
1 Correct 118 ms 492 KB Ok! 1522 queries used.
2 Correct 107 ms 488 KB Ok! 1513 queries used.
3 Correct 108 ms 468 KB Ok! 1550 queries used.
4 Correct 112 ms 496 KB Ok! 1573 queries used.
5 Correct 108 ms 488 KB Ok! 1460 queries used.
6 Correct 114 ms 492 KB Ok! 1554 queries used.
# Verdict Execution time Memory Grader output
1 Correct 114 ms 492 KB Ok! 1537 queries used.
2 Correct 106 ms 504 KB Ok! 1513 queries used.