제출 #1267492

#제출 시각아이디문제언어결과실행 시간메모리
1267492trvhung공장들 (JOI14_factories)C++20
100 / 100
6345 ms285044 KiB
#include "factories.h" #include <bits/stdc++.h> // #include <ext/rope> // #include <ext/pb_ds/assoc_container.hpp> // using namespace __gnu_pbds; // using namespace __gnu_cxx; using namespace std; // #define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update> #define ll long long #define ull unsigned long long #define ld long double #define pb push_back #define bit(mask, i) ((mask >> i) & 1) #define el '\n' #define F first #define S second template <class X, class Y> bool maximize(X &x, const Y &y) { return (x < y ? x = y, 1 : 0); } template <class X, class Y> bool minimize(X &x, const Y &y) { return (x > y ? x = y, 1 : 0); } const int INF = 1e9; const ll LINF = 1e18; const int MOD = 1e9 + 7; const int MULTI = 0; const ld eps = 1e-9; const int dx[4] = {0, 1, 0, -1}, dy[4] = {1, 0, -1, 0}; // R D L U const int ddx[4] = {-1, 1, 1, -1}, ddy[4] = {1, 1, -1, -1}; // UR DR DL UL const char cx[4] = {'R', 'D', 'L', 'U'}; const ll base = 31; const int nMOD = 2; const ll mods[] = {(ll)1e9 + 10777, (ll)1e9 + 19777, (ll)1e9 + 3, (ll)1e9 + 3777}; const int N = 5e5 + 5; int n, ti[N], to[N], et[N], timeDfs; ll d[N], res; vector<pair<int, int>> adj[N]; vector<pair<int, ll>> aux_adj[N]; bool A[N], B[N]; void pre_dfs(int u, int p) { ti[u] = ++timeDfs; et[timeDfs] = u; for (auto v: adj[u]) if (v.F != p) pre_dfs(v.F, u); to[u] = timeDfs; } bool is_ancestor(int u, int v) { return ti[u] <= ti[v] && ti[v] <= to[u]; } namespace LCA { const int LOG = 19; int ti[N], et[2 * N], lg2[2 * N], timeDfs = 1, h[N]; ll d[N]; pair<int, int> st[LOG + 1][2 * N]; void dfs(int u, int p) { ti[u] = timeDfs; et[timeDfs++] = u; for (auto g: adj[u]) { int v = g.F, w = g.S; if (v != p) { h[v] = h[u] + 1; d[v] = d[u] + w; dfs(v, u); et[timeDfs++] = u; } } } void preprocess() { lg2[1] = 0; for (int i = 2; i <= 2 * n; ++i) lg2[i] = lg2[i / 2] + 1; for (int i = 1; i <= 2 * n; ++i) st[0][i] = make_pair(h[et[i]], et[i]); for (int j = 1; j <= LOG; ++j) for (int i = 1; i + (1 << j) - 1 <= 2 * n; ++i) st[j][i] = min(st[j - 1][i], st[j - 1][i + (1 << (j - 1))]); } pair<int, int> query(int l, int r) { int k = lg2[r - l + 1]; return min(st[k][l], st[k][r - (1 << k) + 1]); } int lca(int u, int v) { if (ti[u] > ti[v]) swap(u, v); return query(ti[u], ti[v]).S; } ll dist(int u, int v) { return d[u] + d[v] - 2 * d[lca(u, v)]; } void build() { dfs(1, 0); preprocess(); } } struct IT { ll st[4 * N], lazy[4 * N]; void build(int id, int l, int r) { st[id] = LINF; if (l == r) return; int mid = (l + r) >> 1; build(id << 1, l, mid); build(id << 1 | 1, mid + 1, r); } void push(int id, int l, int r) { ll &t = lazy[id]; if (t == 0) return; st[id << 1] += t; lazy[id << 1] += t; st[id << 1 | 1] += t; lazy[id << 1 | 1] += t; t = 0; } void updateMass(int id, int l, int r, int u, ll x) { if (l == r) return st[id] = x, void(); int mid = (l + r) >> 1; push(id, l, r); if (u <= mid) updateMass(id << 1, l, mid, u, x); else updateMass(id << 1 | 1, mid + 1, r, u, x); st[id] = min(st[id << 1], st[id << 1 | 1]); } void update(int id, int l, int r, int u, int v, ll x) { if (u > v) return; if (l == u && r == v) return st[id] += x, lazy[id] += x, void(); int mid = (l + r) >> 1; push(id, l, r); if (v <= mid) update(id << 1, l, mid, u, v, x); else if (u > mid) update(id << 1 | 1, mid + 1, r, u, v, x); else { update(id << 1, l, mid, u, mid, x); update(id << 1 | 1, mid + 1, r, mid + 1, v, x); } st[id] = min(st[id << 1], st[id << 1 | 1]); } } IT; void Init(int N, int A[], int B[], int D[]) { n = N; for (int i = 0; i <= n - 2; ++i) { A[i]++; B[i]++; adj[A[i]].push_back(make_pair(B[i], D[i])); adj[B[i]].push_back(make_pair(A[i], D[i])); } pre_dfs(1, 0); LCA::build(); IT.build(1, 1, n); } int build_auxiliary_tree(vector<int> &vers) { int sz = (int) vers.size(); sort(vers.begin(), vers.end(), [&](int A, int B){ return ti[A] < ti[B]; }); for (int i = 0; i < sz - 1; ++i) { int lca = LCA::lca(vers[i], vers[i + 1]); vers.push_back(lca); } sort(vers.begin(), vers.end(), [&](int A, int B){ return ti[A] < ti[B]; }); vers.resize(unique(vers.begin(), vers.end()) - vers.begin()); vector<int> stack; int aux_root = vers[0]; stack.push_back(aux_root); for (int i = 1; i < (int) vers.size(); ++i) { int u = vers[i]; while (!stack.empty() && !is_ancestor(stack.back(), u)) stack.pop_back(); assert(!stack.empty()); int last = stack.back(); aux_adj[last].push_back(make_pair(u, LCA::dist(last, u))); stack.push_back(u); } return aux_root; } void dfs1(int u, int p) { for (auto g: aux_adj[u]) { int v = g.F; ll w = g.S; if (v == p) continue; d[v] = d[u] + w; dfs1(v, u); } } void dfs2(int u, int p) { for (auto g: aux_adj[u]) { int v = g.F; ll w = g.S; if (v == p) continue; IT.update(1, 1, n, ti[v], to[v], -w); IT.update(1, 1, n, 1, ti[v] - 1, w); IT.update(1, 1, n, to[v] + 1, n, w); if (B[v]) minimize(res, IT.st[1]); dfs2(v, u); IT.update(1, 1, n, ti[v], to[v], w); IT.update(1, 1, n, 1, ti[v] - 1, -w); IT.update(1, 1, n, to[v] + 1, n, -w); } } ll Query(int S, int X[], int T, int Y[]) { vector<int> vers; for (int i = 0; i < S; ++i) { A[++X[i]] = 1; vers.push_back(X[i]); } for (int i = 0; i < T; ++i) { B[++Y[i]] = 1; vers.push_back(Y[i]); } int root = build_auxiliary_tree(vers); dfs1(root, 0); for (int i = 0; i < S; ++i) IT.updateMass(1, 1, n, ti[X[i]], d[X[i]]); res = (B[root] ? IT.st[1] : LINF); dfs2(root, 0); for (auto x: vers) aux_adj[x].clear(), d[x] = 0; for (int i = 0; i < S; ++i) { IT.updateMass(1, 1, n, ti[X[i]], LINF); A[X[i]] = 0; } for (int i = 0; i < T; ++i) B[Y[i]] = 0; return res; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...