Submission #236020

#TimeUsernameProblemLanguageResultExecution timeMemory
236020DS007Factories (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]; 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 + (1 << i) < euler.size(); j++) sparse[j][i] = merge(sparse[j][i - 1], sparse[j + (1 << (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 - (1 << 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; } }

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 + (1 << i) < euler.size(); j++)
                         ~~^~~~~~~~~~~~~~
factories.cpp:47:62: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         for (int j = 0; j < euler.size() && j - 1 + (1 << i) < euler.size(); j++)
                                             ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...