제출 #1230887

#제출 시각아이디문제언어결과실행 시간메모리
1230887wcarrotw공장들 (JOI14_factories)C++17
33 / 100
8090 ms154044 KiB
#include "factories.h"
#include <bits/stdc++.h>
using namespace std;

#define fi first
#define se second
#define ll long long
#define bit(mask, i) ((mask >> i) & 1)
#define pb push_back

const int N = 5e5 + 10;
const int LG = 20;
const ll inf = 1e18;

vector<pair<int, ll>> a[N], vtree[N];
int n, timer;
int tin[N], tout[N], tour[N], par[N], jump[N][LG], depth[N];
ll dist[N];
unordered_map<int, int> mp, color;
vector<int> type;
vector<ll> dp1, dp2;

bool cmp(int u, int v) {
    return tin[u] < tin[v];
}

void dfs1(int u, int p) {
    par[u] = p;
    tin[u] = ++timer;
    tour[timer] = u;
    for (auto &[v, w] : a[u]) {
        if (v == p) continue;
        depth[v] = depth[u] + 1;
        dist[v] = dist[u] + w;
        dfs1(v, u);
    }
    tout[u] = timer;
}

void build_jump() {
    for (int i = 0; i < n; ++i) {
        jump[i][0] = par[i];
    }
    for (int j = 1; j < LG; ++j) {
        for (int i = 0; i < n; ++i) {
            if (jump[i][j - 1] != -1) {
                jump[i][j] = jump[jump[i][j - 1]][j - 1];
            }
        }
    }
}

int take(int u, int v) {
    int delta = depth[u] - depth[v];
    for (int i = 0; (1 << i) <= delta; ++i) {
        if (bit(delta, i)) {
            u = jump[u][i];
        }
    }
    return u;
}

int lca(int u, int v) {
    if (depth[u] != depth[v]) {
        if (depth[u] < depth[v]) swap(u, v);
        u = take(u, v);
    }
    if (u == v) return u;
    for (int i = LG - 1; i >= 0; --i) {
        if (jump[u][i] != jump[v][i]) {
            u = jump[u][i];
            v = jump[v][i];
        }
    }
    return jump[u][0];
}

bool is_ancestor(int u, int v) {
    return tin[u] <= tin[v] && tout[v] <= tout[u];
}

ll get(int u, int v) {
    return dist[u] + dist[v] - 2 * dist[lca(u, v)];
}

vector<int> buildtree(vector<int> tree) {
    sort(tree.begin(), tree.end(), cmp);
    int sz = tree.size();
    for (int i = 0; i < sz - 1; ++i) {
        tree.pb(lca(tree[i], tree[i + 1]));
    }
    sort(tree.begin(), tree.end());
    tree.erase(unique(tree.begin(), tree.end()), tree.end());
    sort(tree.begin(), tree.end(), cmp);
    stack<int> st;
    st.push(tree[0]);
    for (int i = 1; i < tree.size(); ++i) {
        while (!is_ancestor(st.top(), tree[i])) st.pop();
        vtree[st.top()].pb({tree[i], get(st.top(), tree[i])});
        st.push(tree[i]);
    }
    return tree;
}

int change(int x) {
    return mp[x];
}

void dfs2(int u, int p) {
    int _u = change(u);
    if (color[u] == 1) dp1[_u] = 0;
    if (color[u] == 2) dp2[_u] = 0;

    for (auto &[v, w] : vtree[u]) {
        if (v == p) continue;
        dfs2(v, u);
        int _v = change(v);
        dp1[_u] = min(dp1[_u], dp1[_v] + w);
        dp2[_u] = min(dp2[_u], dp2[_v] + w);
    }
}

// ============================
// Required functions for JOI:
// ============================

void Init(int N_, int A[], int B[], int D[]) {
    n = N_;
    for (int i = 0; i < n - 1; ++i) {
        int u = A[i], v = B[i]; ll w = D[i];
        a[u].pb({v, w});
        a[v].pb({u, w});
    }
    timer = 0;
    dfs1(0, -1);
    build_jump();
}

long long Query(int S, int X[], int T, int Y[]) {
    vector<int> tree;
    for (int i = 0; i < S; ++i) {
        tree.pb(X[i]);
        color[X[i]] = 1;
    }
    for (int i = 0; i < T; ++i) {
        tree.pb(Y[i]);
        color[Y[i]] = 2;
    }

    tree = buildtree(tree);
    int root = tree[0], sz = tree.size();
    for (int i = 0; i < sz; ++i) {
        type.pb(color[tree[i]]);
        mp[tree[i]] = i;
    }

    dp1.assign(sz, inf), dp2.assign(sz, inf);
    dfs2(root, -1);

    ll res = inf;
    for (int i = 0; i < sz; ++i) {
        res = min(res, dp1[i] + dp2[i]);
    }

    // Clear memory
    for (int i = 0; i < sz; ++i) {
        vtree[tree[i]].clear();
    }
    color.clear(); mp.clear(); type.clear(); dp1.clear(); dp2.clear();

    return res;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...