Submission #236019

#TimeUsernameProblemLanguageResultExecution timeMemory
236019DS007Factories (JOI14_factories)C++14
0 / 100
21 ms12544 KiB
#include <bits/stdc++.h>
using namespace std;

const int N = 5e5;
vector<pair<int, long long>> adj[N];
int n, m;

vector<int> euler, depth;
int first[N], last[N], l2[N * 2];
long long dep[N], p2[N * 2];
int sparse[N * 2][22];
int c = 0;

int sub[N], par[N];
long long ans[N];
bool isCen[N];
int size = 0;

// LCA begins
void pre(int v, int p = -1, long long d = 0, int de = 0) {
    first[v] = c++;
    dep[v] = d;
    euler.push_back(v);
    depth.push_back(de);

    for (auto i : adj[v]) {
        if (i.first != p) {
            pre(i.first, v, d + i.second, de + 1);
            euler.push_back(v);
            depth.push_back(de);
            c++;
        }
    }

    last[v] = c - 1;
}

int merge(int a, int b) {
    return depth[a] < depth[b] ? a : b;
}

void build_sparse() {
    for (int i = 0; i < euler.size(); i++)
        sparse[i][0] = i;

    for (int i = 1; i <= l2[euler.size()]; i++) {
        for (int j = 0; j < euler.size() && j - 1 + p2[i] < euler.size(); j++)
            sparse[j][i] = merge(sparse[j][i - 1], sparse[j + (p2[i - 1])][i - 1]);
    }
}

int lca(int u, int v) {
    if (u == v) return u;
    int f1 = min(first[u], first[v]), f2 = max(first[v], first[u]), diff = f2 - f1;
    int dx = l2[diff];
    return euler[merge(sparse[f1][dx], sparse[f2 - (p2[dx])][dx])];
}

long long dist(int u, int v) {
    return dep[u] + dep[v] - 2 * dep[lca(u, v)];
}
// LCA ends

// Centroid decomposition begins
void calc(int v, int p = -1) { // Pre calculate subtree sizes
    sub[v] = 1;
    size++;
    for (auto i : adj[v]) {
        if (i.first != p && !isCen[v])
            calc(i.first, v), sub[v] += sub[i.first];
    }
}

int find(int v, int p = -1) { // Find the centroid in current subtree
    for (auto i : adj[v]) {
        if (i.first != p && !isCen[i.first] && sub[i.first] > size / 2)
            return find(i.first, v);
    }
    return v;
}

void decompose(int v, int p = -1) {
    size = 0; // Stores size of current subtree
    calc(v);
    int centroid = find(v);
    par[centroid] = p;
    isCen[centroid] = true;

    for (auto i : adj[centroid]) {
        if (i.first != p && !isCen[i.first])
            decompose(i.first, centroid);
    }
}
// Centroid decomposition ends

void update(int v) {
    int p = v;
    while (p != -1) {
        ans[p] = min(ans[p], dist(p, v));
        p = par[p];
    }
}

long long query(int v) {
    int p = v;
    long long val = 1e18;
    while (p != -1) {
        val = min(val, ans[p] + dist(p, v));
        p = par[p];
    }
    return val;
}

void revert(int v) {
    int p = v;
    while (p != -1) {
        ans[p] = 1e18;
        p = par[p];
    }
}

long long Query(int S, int X[], int T, int Y[]) {
    for (int i = 0; i < S; i++)
        update(X[i]);
    long long ans = 1e18;
    for (int i = 0; i < T; i++)
        ans = min(ans, query(Y[i]));
    for (int i = 0; i < S; i++)
        revert(X[i]);
    return ans;
}

void Init(int N, int A[], int B[], int D[]) {
    n = N;
    for (int i = 0; i < n - 1; i++) {
        adj[A[i]].emplace_back(B[i], D[i]);
        adj[B[i]].emplace_back(A[i], D[i]);
    }

    pre(0);
    build_sparse();
    decompose(0);
    fill(ans, ans + N, 1e18);

    for (int i = 2, j = 1; i < N * 2; i *= 2, j++) {
        for (int k = i; k < i * 2 && k < N * 2; k++)
            l2[k] = j;
    }
    
    p2[0] = 1;
    for (int i = 1; i < N * 2; i++)
        p2[i] = p2[i - 1] * 2;
}

Compilation message (stderr)

factories.cpp: In function 'void build_sparse()':
factories.cpp:43:23: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     for (int i = 0; i < euler.size(); i++)
                     ~~^~~~~~~~~~~~~~
factories.cpp:47:27: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         for (int j = 0; j < euler.size() && j - 1 + p2[i] < euler.size(); j++)
                         ~~^~~~~~~~~~~~~~
factories.cpp:47:59: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         for (int j = 0; j < euler.size() && j - 1 + p2[i] < euler.size(); j++)
                                             ~~~~~~~~~~~~~~^~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...