제출 #1344636

#제출 시각아이디문제언어결과실행 시간메모리
1344636MisterReaperSpy 3 (JOI24_spy3)C++20
99 / 100
41 ms3984 KiB
#include "Aoi.h"
#include "bits/stdc++.h"

using i64 = long long;

namespace {
    #ifdef DEBUG
        #include "/home/ahmetalp/Desktop/Workplace/debug.h"
    #else
        #define debug(...) void(23)
    #endif

    template<typename T>
    bool chmin(T& a, T b) {
        if (a > b) {
            a = b;
            return true;
        }
        return false;
    }

    template<typename T>
    using min_pq = std::priority_queue<T, std::vector<T>, std::greater<T>>;

    constexpr i64 inf = i64(1E18);

    std::string encode(i64 x, int b) {
        assert(x < (1LL << b));
        std::string res = "";
        for (int i = 0; i < b; ++i) {
            res += char('0' + (x >> i & 1));
        }
        return res;
    }

    i64 fac(int n) {
        i64 res = 1;
        for (int i = 1; i <= n; ++i) {
            res *= i;
        }
        return res;
    }

    i64 factor_number(std::vector<int> p) {
        int n = int(p.size());
        if (n == 0) {
            return 0;
        }
        i64 res = 0;
        for (int i = 0; i < p[0]; ++i) {
            res += fac(n - 1);
        }
        for (int i = 1; i < n; ++i) {
            if (p[i] > p[0]) {
                p[i] -= 1;
            }
        }
        p.erase(p.begin());
        res += factor_number(p);
        assert(res < fac(n));
        return res;
    }

}  // namespace

std::string aoi(int N, int M, int Q, int K, std::vector<int> A,
                std::vector<int> B, std::vector<i64> C,
                std::vector<int> T, std::vector<int> X) {
    std::string s;

    std::vector<std::vector<int>> adj(N);
    for (int i = 0; i < M; ++i) {
        adj[A[i]].emplace_back(i);
        adj[B[i]].emplace_back(i);
    }
    std::vector<i64> dis(N, inf);
    min_pq<std::pair<i64, int>> que;
    std::vector<int> prv(N, -1);
    que.emplace(dis[0] = 0, 0);
    while (!que.empty()) {
        auto[d, v] = que.top();
        que.pop();
        if (d != dis[v]) {
            continue;
        }
        for (auto i : adj[v]) {
            int u = A[i] ^ B[i] ^ v;
            if (chmin(dis[u], d + C[i])) {
                prv[u] = i;
                que.emplace(dis[u], u);
            }
        }
    }

    std::vector<std::vector<int>> tree(N);
    for (int v = 1; v < N; ++v) {
        int u = A[prv[v]] ^ B[prv[v]] ^ v;
        debug(u, v);
        tree[u].emplace_back(v);
    }

    int tim = 0;
    std::vector<int> tin(N);
    std::vector<int> tout(N);
    std::vector<int> dep(N);
    auto dfs1 = [&](auto&& self, int v) -> void {
        tin[v] = tim++;
        for (auto u : tree[v]) {
            dep[u] = dep[v] + 1;
            self(self, u);
        }
        tout[v] = tim;
    };
    dfs1(dfs1, 0);

    std::vector<int> ord(Q);
    std::iota(ord.begin(), ord.end(), 0);
    std::sort(ord.begin(), ord.end(), [&](auto lhs, auto rhs) {
        return tin[T[lhs]] < tin[T[rhs]];
    });

    debug(ord);
    debug(factor_number(ord));

    s += encode(factor_number(ord), 45);

    std::vector<std::vector<int>> sub(N);
    for (int i = 0; i < Q; ++i) {
        sub[T[ord[i]]].emplace_back(i);
    }

    std::vector<std::pair<int, int>> g;

    auto transform = [&](auto&& self, int v) -> std::pair<int, int> {
        // debug(v);
        std::vector<std::pair<int, int>> vec;
        if (!sub[v].empty()) {
            for (int i = sub[v].front(); i <= sub[v].back(); ++i) {
                g.emplace_back(sub[v].front(), i);
            }
            vec.emplace_back(sub[v].front(), sub[v].back());
        }
        for (auto u : tree[v]) {
            auto r = self(self, u);
            if (r.first != -1) {
                vec.emplace_back(r);
            }
        }
        if (vec.empty()) {
            return {-1, -1};
        }
        std::sort(vec.begin(), vec.end());
        for (int i = 1; i < int(vec.size()); ++i) {
            g.emplace_back(vec[0].first, vec[i].second);
        }
        return {vec.front().first, vec.back().second};
    };
    transform(transform, 0);

    std::sort(g.begin(), g.end(), [&](auto lhs, auto rhs) -> bool {
        if (lhs.second - lhs.first == rhs.second - rhs.first) {
            return lhs.first < rhs.first;
        }
        return lhs.second - lhs.first < rhs.second - rhs.first;
    });

    debug(g);
    assert(int(g.size()) == 2 * Q - 1);

    std::vector<std::array<int, 2>> bin(2 * Q - 1, {-1, -1});
    for (int i = Q; i < 2 * Q - 1; ++i) {
        for (int j = 0; j < i; ++j) {
            if (g[j].first == g[i].first) {
                std::pair<int, int> oth = {g[j].second + 1, g[i].second};
                int k = std::find(g.begin(), g.end(), oth) - g.begin();
                if (k != 2 * Q - 1) {
                    bin[i] = {j, k};
                }
            } 
        }
    }

    std::vector<i64> f(Q + 1);
    f[1] = 1;
    for (int i = 2; i <= Q; ++i) {
        for (int j = 1; j < i; ++j) {
            f[i] += f[j] * f[i - j];
        }
    }

    auto encode_catalan = [&](auto&& self, int v) -> i64 {
        if (g[v].first == g[v].second) {
            return 0;
        }
        i64 id_tree = 0;
        int lc = bin[v][0];
        int rc = bin[v][1];
        int s = g[v].second - g[v].first + 1;
        int sl = g[lc].second - g[lc].first + 1;
        int sr = g[rc].second - g[rc].first + 1;
        for (int i = 1; i < sl; ++i) {
            id_tree += f[i] * f[s - i];
        }
        id_tree += self(self, lc) * f[sr];
        id_tree += self(self, rc);
        assert(id_tree < f[s]);
        return id_tree;
    };
    i64 id_tree = encode_catalan(encode_catalan, 2 * Q - 2);
    
    debug(id_tree);

    s += encode(id_tree, 24);

    std::vector<std::vector<int>> add(K);
    for (int i = 0; i < Q; ++i) {
        int v = T[ord[i]];
        while (v != 0) {
            int e = prv[v];
            int ide = std::find(X.begin(), X.end(), e) - X.begin();
            if (ide != K) {
                add[ide].emplace_back(i);
            }
            v = A[e] ^ B[e] ^ v;
        }
    }

    for (auto v : add) {
        debug(v);
        if (v.empty()) {
            debug(31);
            s += encode(31, 5);
        } else {
            int l = v.front();
            int r = v.back();
            int id = int(std::find(g.begin(), g.end(), std::pair{l, r}) - g.begin());
            debug(id);
            s += encode(id, 5);
        }
    }

    debug();
    debug();
    debug();

    return s;
}
#include "Bitaro.h"
#include "bits/stdc++.h"

using i64 = long long;

namespace {
    #ifdef DEBUG
        #include "/home/ahmetalp/Desktop/Workplace/debug.h"
    #else
        #define debug(...) void(23)
    #endif

    template<typename T>
    bool chmin(T& a, T b) {
        if (a > b) {
            a = b;
            return true;
        }
        return false;
    }

    template<typename T>
    using min_pq = std::priority_queue<T, std::vector<T>, std::greater<T>>;

    constexpr i64 inf = i64(1E18);

    i64 decode(std::string s) {
        i64 res = 0;
        for (int i = 0; i < int(s.size()); ++i) {
            if (s[i] == '1') {
                res += 1LL << i;
            }
        }
        return res;
    }

    i64 fac(int n) {
        i64 res = 1;
        for (int i = 1; i <= n; ++i) {
            res *= i;
        }
        return res;
    }

    std::vector<int> decode_factor(int n, i64 x) {
        if (n == 0) {
            assert(x == 0);
            return {};
        }
        assert(x < fac(n));
        std::vector<int> p;
        for (int i = 0; i < n; ++i) {
            if (x >= fac(n - 1)) {
                x -= fac(n - 1);
            } else {
                p.emplace_back(i);
                auto q = decode_factor(n - 1, x);
                for (auto& j : q) {
                    if (j >= i) {
                        j += 1;
                    }
                }
                p.insert(p.end(), q.begin(), q.end());
                break;
            }
        }
        return p;
    }

}  // namespace

void bitaro(int N, int M, int Q, int K, std::vector<int> A, std::vector<int> B,
            std::vector<i64> C, std::vector<int> T, std::vector<int> X,
            std::string s) {
    std::vector<std::vector<int>> adj(N);
    for (int i = 0; i < M; ++i) {
        adj[A[i]].emplace_back(i);
        adj[B[i]].emplace_back(i);
    }

    i64 ord_number = decode(s.substr(0, 45));
    s = s.substr(45);
    debug(ord_number);
    std::vector<int> ord = decode_factor(Q, ord_number);
    debug(ord);

    std::vector<i64> f(Q + 1);
    f[1] = 1;
    for (int i = 2; i <= Q; ++i) {
        for (int j = 1; j < i; ++j) {
            f[i] += f[j] * f[i - j];
        }
    }

    i64 id_tree = decode(s.substr(0, 24));
    debug(id_tree);
    s = s.substr(24);

    std::vector<std::pair<int, int>> g(2 * Q - 1);
    int p = 2 * Q - 2;
    std::vector<std::array<int, 2>> bin(2 * Q - 1, {-1, -1});
    auto decode_catalan = [&](auto&& self, int v, i64 x) -> void {
        if (g[v].first == g[v].second) {
            assert(x == 0);
            return;
        }
        int s = g[v].second - g[v].first + 1;
        assert(x < f[s]);
        int lc = --p;
        int rc = --p;
        bin[v] = {lc, rc};
        for (int i = 1; i < s; ++i) {
            debug(i);
            if (x >= f[i] * f[s - i]) {
                x -= f[i] * f[s - i];
            } else {
                debug(g[v], i);
                g[lc] = {g[v].first, g[v].first + i - 1};
                g[rc] = {g[v].first + i, g[v].second};
                self(self, lc, x / f[s - i]);
                self(self, rc, x % f[s - i]);
                return;
            }
        }
    };
    g[2 * Q - 2] = {0, Q - 1};
    decode_catalan(decode_catalan, 2 * Q - 2, id_tree);

    std::sort(g.begin(), g.end(), [&](auto lhs, auto rhs) -> bool {
        if (lhs.second - lhs.first == rhs.second - rhs.first) {
            return lhs.first < rhs.first;
        }
        return lhs.second - lhs.first < rhs.second - rhs.first;
    });

    debug(g);

    std::vector<std::vector<int>> st(N);
    std::vector<std::vector<int>> add(K);
    for (int i = 0; i < K; ++i) {
        int id = decode(s.substr(0, 5));
        debug(id);
        if (id == 31) {
            debug("emp");
            // empty
        } else {
            int l = g[id].first;
            int r = g[id].second;
            for (int j = l; j <= r; ++j) {
                st[T[ord[j]]].emplace_back(X[i]);
            }
            debug(l, r);
        }
        s = s.substr(5);
    }

    assert(s.empty());
    debug(st);

    for (auto ask_v : T) {
        debug(ask_v, st[ask_v]);
        auto cst = C;
        for (auto i : X) {
            cst[i] = inf;
        }
        for (auto i : st[ask_v]) {
            cst[i] = 0;
        }
        std::vector<i64> dis(N, inf);
        std::vector<int> prv(N, -1);
        min_pq<std::pair<i64, int>> que;
        que.emplace(dis[0] = 0, 0);
        while (!que.empty()) {
            auto[d, v] = que.top();
            que.pop();
            if (d != dis[v]) {
                continue;
            }
            for (auto i : adj[v]) {
                int u = A[i] ^ B[i] ^ v;
                if (chmin(dis[u], d + cst[i])) {
                    prv[u] = i;
                    que.emplace(dis[u], u);
                }
            }
        }
        std::vector<int> res;
        int v = ask_v;
        while (v != 0) {
            res.emplace_back(prv[v]);
            v = A[prv[v]] ^ B[prv[v]] ^ v;
        }
        std::reverse(res.begin(), res.end());
        answer(res);
    }
}
#Verdict Execution timeMemoryGrader output
Fetching results...