Submission #1336338

#TimeUsernameProblemLanguageResultExecution timeMemory
1336338MisterReaperShopping (JOI21_shopping)C++20
100 / 100
74 ms21808 KiB
#include "Anna.h"
#include "bits/stdc++.h"

namespace {
    #ifdef DEBUG
        #include "../../debug.h"
        #define debug(...) std::cerr << "A:" << __LINE__ << ":[" << #__VA_ARGS__ << "]:"; debug_out(__VA_ARGS__)
    #else
        #define debug(...) void(23)
    #endif

    int lg(int x) {
        if (x <= 0) {
            return 0;
        }
        return std::__lg(x);
    }

    int mode;
    int counter = 0;
    std::vector<int> buffer;

    int N;
    int L;
    int R;

    constexpr int LOG = 20;
    constexpr int MAX_DEP = 13;
    constexpr int ALICE_MAX = 18;

    int l;
    int r;
    int d;
    std::vector<int> path;
    void build1() {
        l = 0;
        r = N - 1;
        d = 0;
        while (l != r && d != MAX_DEP) {
            int mid = (l + r) >> 1;
            if (R <= mid) {
                path.emplace_back(0);
                r = mid;
            } else if (mid + 1 <= L) {
                path.emplace_back(1);
                l = mid + 1;
            } else {
                break;
            }
            d += 1;
        }
        debug(l, r, d);
        debug(path);
        if (d < 2) {
            SendA(0);
            SendA(0);
            SendA(d);
            counter += 3 + d;
            for (int i = 0; i < d; ++i) {
                SendA(path[i]);
            }
        } else {
            for (int i = 0; i < 4; ++i) {
                SendA((d + 2) >> (3 - i) & 1);
            }
            counter += 4 + d;
            for (int i = 0; i < d; ++i) {
                SendA(path[i]);
            }
        }
    }

    int lo;
    int hi;
    int mid;
    int ls_lo;
    int rs_lo;
    int ls_hi;
    int rs_hi;
    void read() {
        int dif = 0;
        int len = lg(mid - lo);
        if (len + 1 != int(buffer.size())) {
            return;
        }
        for (int i = 0; i <= len; ++i) {
            dif += buffer[i] << i;
        }
        int ls_mid = ls_lo - dif;
        int rs_mid = ls_mid + mid;
        debug(ls_lo, rs_lo);
        debug(ls_hi, rs_hi);
        debug(ls_mid, rs_mid);
        debug(dif, len);
        debug(lo, hi, mid);
        debug();
        if (ls_mid <= L && R <= rs_mid) {
            ls_hi = ls_mid;
            rs_hi = rs_mid;
            hi = mid;
            SendA(0);
        } else {
            ls_lo = ls_mid;
            rs_lo = rs_mid;
            lo = mid;
            SendA(1);
        }
        mid = (lo + hi) >> 1;
        buffer.clear();
        counter += 1;
        debug(counter);
    }
    void build2() {
        int m = (l + r) >> 1;
        lo = 0;
        hi = r - l;
        ls_lo = m;
        rs_lo = m;
        ls_hi = l;
        rs_hi = r;
        mid = (lo + hi) >> 1;
    }

    std::vector<int> ids;
}  // namespace

void InitA(int N, int L, int R) {
    ::N = N;
    ::L = L;
    ::R = R;
    build1();
    if (d == MAX_DEP) {
        for (int i = l; i <= r; ++i) {
            ids.emplace_back(i);
        }
        mode = 2;
        return;
    }
    build2();
    mode = 0;
}

void ReceiveA(bool x) {
    buffer.emplace_back(x);
    if (mode == 0) {
        read();
        if (counter == ALICE_MAX) {
            debug("ids");
            mode = 1;
        }
        return;
    } 
    if (mode == 1) {
        if (int(buffer.size()) == LOG) {
            debug(ls_lo, rs_lo);
            debug(ls_hi, rs_hi);
            int p = 0;
            for (int i = 0; i < LOG; ++i) {
                p += buffer[i] << i;
            }
            for (int i = ls_hi; i < ls_lo; ++i) {
                ids.emplace_back(i);
            }
            ids.emplace_back(p);
            for (int i = rs_lo + 1; i <= rs_hi; ++i) {
                ids.emplace_back(i);
            }
            mode = 2;
            buffer.clear();
        } 
        return;
    } 
    if (mode == 2) {
        // do nothing
    }
}

int Answer() {
    // debug(ids);
    std::vector<int> tree = buffer;
    int p = 0;
    std::vector<int> stk;
    for (auto i : tree) {
        if (ids[p] > R) {
            break;
        }
        if (i == 0) {
            stk.pop_back();
        } else {
            stk.emplace_back(ids[p]);
            p += 1;
        }
    }
    debug(stk);
    assert(!stk.empty());
    int ans = -1;
    for (auto i : stk) {
        if (i >= L) {
            ans = i;
            break;
        }
    }
    debug(ans);
    assert(L <= ans && ans <= R);
    return ans;
}
#include "Bruno.h"
#include "bits/stdc++.h"

namespace {
    #ifdef DEBUG
        #include "../../debug.h"
        #define debug(...) std::cerr << "B:" << __LINE__ << ":[" << #__VA_ARGS__ << "]:"; debug_out(__VA_ARGS__)
    #else
        #define debug(...) void(23)
    #endif

    int lg(int x) {
        if (x <= 0) {
            return 0;
        }
        return std::__lg(x);
    }

    int mode;
    int counter = 0;
    std::vector<int> buffer;

    int N;
    std::vector<int> P;

    constexpr int LOG = 20;
    constexpr int MAX_DEP = 13;
    constexpr int ALICE_MAX = 18;

    int l;
    int r;
    int d;
    std::vector<int> path;
    void build1() {
        l = 0;
        r = N - 1;
        int p = 0;
        while (l != r && p != d) {
            int mid = (l + r) >> 1;
            if (path[p] == 0) {
                r = mid;
            } else {
                l = mid + 1;
            }
            p += 1;
        }
        debug(l, r, d);
    }

    int lo;
    int hi;
    int mid;
    std::vector<int> ls;
    std::vector<int> rs;
    void send() {
        int dif = ls[lo] - ls[mid];
        int len = lg(mid - lo);
        debug(ls[lo], rs[lo]);
        debug(ls[hi], rs[hi]);
        debug(ls[mid], rs[mid]);
        debug(dif, len);
        debug(lo, hi, mid);
        debug();
        for (int i = 0; i <= len; ++i) {
            SendB(dif >> i & 1);
        }
    }
    void build2() {
        int m = (l + r) >> 1;
        int ll = m;
        int rr = m;
        while (true) {
            ls.emplace_back(ll);
            rs.emplace_back(rr);
            if (ll - 1 >= l) {
                if (rr + 1 <= r) {
                    (P[ll - 1] > P[rr + 1] ? ll -= 1 : rr += 1);
                } else {
                    ll -= 1;
                }
            } else {
                if (rr + 1 <= r) {
                    rr += 1;
                } else {
                    break;
                }
            }
        }
        lo = 0;
        hi = r - l;
        mid = (lo + hi) >> 1;
        send();
    }

    std::vector<int> ids;

    std::vector<int> create_cartesian_tree() {
        std::vector<int> res;
        std::vector<int> stk;
        for (auto i : ids) {
            while (!stk.empty() && P[stk.back()] > P[i]) {
                res.emplace_back(0);
                stk.pop_back();
            }
            res.emplace_back(1);
            stk.emplace_back(i);
        }
        return res;
    }
}  // namespace

void InitB(int N, std::vector<int> P) {
    ::N = N;
    ::P = P;
    mode = 0;
}

void ReceiveB(bool y) {
    buffer.emplace_back(y);
    if (mode == 0) {
        debug(buffer);
        if (int(buffer.size()) == 3 && buffer[0] == 0 && buffer[1] == 0) {
            counter += 3;
            d = buffer[2];
            mode = 1;
            buffer.clear();
        } else if (int(buffer.size() == 4)) {
            counter += 4;
            d = 0;
            for (int i = 0; i < 4; ++i) {
                d += buffer[i] << (3 - i);
            }
            d -= 2;
            mode = 1;
            buffer.clear();
        }
    }
    if (mode == 1) {
        if (int(buffer.size()) == d) {
            counter += d;
            path.resize(d);
            for (int i = 0; i < d; ++i) {
                path[i] = buffer[i];
            }
            debug(path);
            build1();
            debug(l, r, d);
            if (d == MAX_DEP) {
                for (int i = l; i <= r; ++i) {
                    ids.emplace_back(i);
                }
                std::vector<int> tree = create_cartesian_tree();
                for (int i = 0; i < int(tree.size()); ++i) {
                    SendB(tree[i]);
                }
                return;
            }
            build2();
            mode = 2;
            buffer.clear();
            return;
        }
    } 
    if (mode == 2) {
        counter += 1;
        if (buffer[0] == 0) {
            hi = mid;
        } else {
            lo = mid;
        }
        buffer.clear();
        debug(counter);
        if (counter == ALICE_MAX) {
            debug(ls[lo], rs[lo]);
            debug(ls[hi], rs[hi]);
            for (int i = ls[hi]; i < ls[lo]; ++i) {
                ids.emplace_back(i);
            }
            int p = std::min_element(P.begin() + ls[lo], P.begin() + rs[lo] + 1) - P.begin();
            ids.emplace_back(p);
            // debug(p);
            for (int i = 0; i < LOG; ++i) {
                SendB(p >> i & 1);
            }
            for (int i = rs[lo] + 1; i <= rs[hi]; ++i) {
                ids.emplace_back(i);
            }
            debug(ids);
            std::vector<int> tree = create_cartesian_tree();
            for (int i = 0; i < int(tree.size()); ++i) {
                SendB(tree[i]);
            }
        } else {
            mid = (lo + hi) >> 1;
            send();
        }
    }
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...