Submission #197793

#TimeUsernameProblemLanguageResultExecution timeMemory
197793DS007Election Campaign (JOI15_election_campaign)C++14
10 / 100
305 ms40672 KiB
#include <bits/stdc++.h> using namespace std; struct query { int a, b, c; }; const int N = 1e5; vector<int> adj[N]; long long subtree[N], dp[N]; vector<query> q[N]; bool check[N]; int parent[N]; int n, m; vector<int> euler, depth; int first[N], last[N]; int c = 0; int sparse[N * 2][18]; long long t[N * 8]; void dfs(int v, int p = -1, int d = 0) { first[v] = c++; parent[v] = p; euler.push_back(v); depth.push_back(d); for (int i : adj[v]) { if (i != p) { dfs(i, v, d + 1); euler.push_back(v); depth.push_back(d); 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 <= log2(n); 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 query_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 = log2(diff); return euler[merge(sparse[f1][dx], sparse[f2 - (1 << dx)][dx])]; } bool cmp(query u, query v) { int lca1 = query_lca(u.a, u.b), lca2 = query_lca(v.a, v.b); if (depth[first[lca1]] == depth[first[lca2]]) return lca1 < lca2; return depth[first[lca1]] < depth[first[lca2]]; } long long query_tree(int v, int l, int r, int tl, int tr) { if (tl > tr) return 0; else if (l == tl && r == tr) return t[v]; int mid = (l + r) / 2; return query_tree(v * 2, l, mid, tl, min(mid, tr)) + query_tree(v * 2 + 1, mid + 1, r, max(tl, mid + 1), tr); } void update(int v, int l, int r, int tl, long long val) { if (l == r && l == tl) { t[v] = val; return; } int mid = (l + r) / 2; if (tl <= mid) update(v * 2, l, mid, tl, val); else update(v * 2 + 1, mid + 1, r, tl, val); t[v] = t[v * 2] + t[v * 2 + 1]; } long long calc(int v, int p) { if (check[v]) return dp[v]; for (int i : adj[v]) { if (i != p) subtree[v] += calc(i, v); } dp[v] = subtree[v]; check[v] = true; return dp[v]; } void solve(int v, int p = -1) { for (int i : adj[v]) { if (i != p) { solve(i, v); subtree[v] += dp[i]; dp[v] += dp[i]; } } for (auto i : q[v]) { long long sum = query_tree(1, 0, euler.size() - 1, /*first[v]*/0, first[i.a]) + query_tree(1, 0, euler.size() - 1, /*first[v]*/0, first[i.b]) + subtree[v] + i.c; dp[v] = max(dp[v], sum); // dp[v] = max(dp[v], subtree[v] + query_tree(1, 0, euler.size() - 1, first[v], first[i.a]) + i.c) + query_tree(1, 0, euler.size() - 1, first[v], first[i.b]); } update(1, 0, euler.size() - 1, first[v], subtree[v] - dp[v]); if (v != 0) update(1, 0, euler.size() - 1, last[v] + 1, dp[v] - subtree[v]); } long long solve(query u) { int lca = query_lca(u.a, u.b); if (!check[lca]) { calc(lca, parent[lca]); } long long sum = query_tree(1, 0, euler.size() - 1, first[lca], first[u.a]) + query_tree(1, 0, euler.size() - 1, first[lca], first[u.b]) + 2 * (dp[lca] - subtree[lca]) + subtree[lca] + u.c; if (sum > dp[lca]) { dp[lca] = sum; update(1, 0, euler.size() - 1, first[lca], subtree[lca] - dp[lca]); if (lca != 0) update(1, 0, euler.size() - 1, last[lca] + 1, dp[lca] - subtree[lca]); } assert(sum >= 0); return sum; } signed main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); cin >> n; for (int i = 0; i < n - 1; i++) { int x, y; cin >> x >> y; x--, y--; adj[x].push_back(y); adj[y].push_back(x); } dfs(0); build_sparse(); cin >> m; for (int i = 0; i < m; i++) { int a, b, c; cin >> a >> b >> c; a--, b--; q[query_lca(a, b)].push_back({a, b, c}); } // for (int i = 0; i < m; i++) cout << query_lca(q[i].a, q[i].b) << endl; solve(0); cout << *max_element(dp, dp + n); }

Compilation message (stderr)

election_campaign.cpp: In function 'void build_sparse()':
election_campaign.cpp:46:23: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     for (int i = 0; i < euler.size(); i++)
                     ~~^~~~~~~~~~~~~~
election_campaign.cpp:50: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++)
                         ~~^~~~~~~~~~~~~~
election_campaign.cpp:50: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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...