Submission #1366399

#TimeUsernameProblemLanguageResultExecution timeMemory
1366399njoopFactories (JOI14_factories)C++20
15 / 100
8101 ms384760 KiB
//#include "factories.h"
#include <bits/stdc++.h>
#define int long long
using namespace std;

struct tree {
    vector<vector<pair<int, int>>> g;
    vector<vector<int>> p;
    vector<int> d, td;
    int n;

    void init(int sz, vector<vector<pair<int, int>>> graph) {
        n = sz;
        g = graph;
        p.assign(n+2, vector<int>(32, 0));
        d.assign(n+2, 0);
        td.assign(n+2, 0);
        dfs(1, -1, 0, 0);
        for(int i=1; i<=30 ; i++) {
            for(int j=1; j<=n; j++) {
                p[j][i] = p[p[j][i-1]][i-1];
            }
        }
    }

    void dfs(int no, int rt, int dis, int tdis) {
        d[no] = dis;
        td[no] = tdis;
        for(auto i: g[no]) {
            if(i.first == rt) continue;
            p[i.first][0] = no;
            dfs(i.first, no, dis+1, tdis+i.second); 
        }
    }

    int lca(int u, int v) {
        if(d[u] > d[v]) swap(u, v);
        int dd = d[v]-d[u];
        for(int i=30; i>=0; i--) {
            if(dd & (1 << i)) {
                v = p[v][i];
            }
        }
        if(u == v) return u;
        for(int i=30; i>=0; i--) {
            if(p[u][i] != p[v][i]) {
                u = p[u][i];
                v = p[v][i];
            }
        }
        return p[u][0];
    }

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

tree tr;

struct cen {
    vector<vector<pair<int, int>>> g;
    vector<int> sz, cp, rem;
    vector<multiset<int>> val;

    void init(int n, vector<vector<pair<int, int>>> graph) {
        g = graph;
        sz.assign(n+2, 0);
        cp.assign(n+2, 0);
        rem.assign(n+2, 0);
        val.assign(n+2, multiset<int>());
        for(int i=1; i<=n; i++) {
            val[i].insert(1e18);
        }
        build(1, -1);
    }

    int get_sz(int no, int rt) {
        sz[no] = 1;
        for(auto i: g[no]) {
            if(i.first == rt || rem[i.first]) continue;
            sz[no] += get_sz(i.first, no);
        }
        return sz[no];
    }

    int get_cent(int no, int rt, int siz) {
        for(auto i: g[no]) {
            if(i.first == rt || rem[i.first]) continue;
            if(sz[i.first] > siz/2) return get_cent(i.first, no, siz);
        }
        return no;
    }

    void build(int no, int rt) {
        int cent = get_cent(no, rt, get_sz(no, rt));
        rem[cent] = 1;
        if(rt == -1) cp[cent] = cent;
        else cp[cent] = rt;
        for(auto i: g[cent]) {
            if(i.first == rt || rem[i.first]) continue;
            build(i.first, cent);
        }
    }

    void update(int u, int rt) {
        val[rt].insert(tr.dist(u, rt));
        while(cp[rt] != rt) {
            rt = cp[rt];
            val[rt].insert(tr.dist(u, rt));
        }
    }

    void remove(int u, int rt) {
        val[rt].erase(val[rt].find(tr.dist(u, rt)));
        while(cp[rt] != rt) {
            rt = cp[rt];
            val[rt].erase(val[rt].find(tr.dist(u, rt)));
        }
    }

    int query(int u, int rt) {
        int ans = tr.dist(u, rt) + *val[rt].begin();
        while(cp[rt] != rt) {
            rt = cp[rt];
            ans = min(ans, tr.dist(u, rt) + *val[rt].begin());
        }
        return ans;
    }
};

cen cent;

void Init(signed N, signed A[], signed B[], signed D[]) {
    vector<vector<pair<int, int>>> g;
    g.assign(N+2, vector<pair<int, int>>());
    for(int i=0; i<N-1; i++) {
        g[A[i]+1].push_back({B[i]+1, D[i]});
        g[B[i]+1].push_back({A[i]+1, D[i]});
    }
    tr.init(N, g);
    cent.init(N, g);
}

long long Query(signed S, signed X[], signed T, signed Y[]) {
    for(int i=0; i<S; i++) {
        cent.update(X[i]+1, X[i]+1);
    }
    int ans = 1e18;
    for(int i=0; i<T; i++) {
        ans = min(ans, cent.query(Y[i]+1, Y[i]+1));
    }
    for(int i=0; i<S; i++) {
        cent.remove(X[i]+1, X[i]+1);
    }
    return ans;
}
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...