Submission #550753

#TimeUsernameProblemLanguageResultExecution timeMemory
550753thuanqvbn03Election Campaign (JOI15_election_campaign)C++17
100 / 100
312 ms37072 KiB
// Flower_On_Stone #include <bits/stdc++.h> using namespace std; const int MAX_N = 100005; const int LOG = 17; struct SegmentTree { private: int treeSize; vector<int> nodes; void initTree(int id, int low, int high) { if (low == high) { nodes[id] = 0; return; } int mid = (low + high) / 2; initTree(id * 2, low, mid); initTree(id * 2 + 1, mid + 1, high); } void update(int id, int low, int high, int left, int right, int val) { if (low > right || high < left) { return; } if (low >= left && high <= right) { nodes[id] += val; return; } int mid = (low + high) / 2; update(id * 2, low, mid, left, right, val); update(id * 2 + 1, mid + 1, high, left, right, val); } int get(int id, int low, int high, int pos) { if (low > pos || high < pos) { return 0; } if (low == high) { return nodes[id]; } int mid = (low + high) / 2; return nodes[id] + (pos <= mid ? get(id * 2, low, mid, pos) : get(id * 2 + 1, mid + 1, high, pos)); } public: void init(int treeSize) { this->treeSize = treeSize; int tmp = 1; while (tmp < treeSize) { tmp *= 2; } nodes.resize(tmp * 2); initTree(1, 1, treeSize); } void update(int left, int right, int val) { update(1, 1, treeSize, left, right, val); } int get(int pos) { return get(1, 1, treeSize, pos); } } smt; struct Plan { int u, v, cost; } plans[MAX_N]; int numCity, numPLan; vector<int> adj[MAX_N], planAt[MAX_N]; int start[MAX_N], stop[MAX_N], depth[MAX_N]; int parent[MAX_N][LOG]; int id; int f[MAX_N], sumF[MAX_N]; void dfs(int node) { for (int level = 0; level < LOG - 1; level++) { parent[node][level + 1] = parent[parent[node][level]][level]; } start[node] = ++id; for (auto &u : adj[node]) { if (u != parent[node][0]) { depth[u] = depth[node] + 1; parent[u][0] = node; dfs(u); } } stop[node] = id; } int lca(int u, int v) { if (depth[u] >depth[v]) { swap(u, v); } for (int level = LOG - 1; level >= 0; level--) { if (depth[parent[v][level]] >= depth[u]) { v = parent[v][level]; } } if (u == v){ return u; } for (int level = LOG - 1; level >= 0; level--) { if (parent[u][level] != parent[v][level]) { u = parent[u][level]; v = parent[v][level]; } } return parent[u][0]; } int jump(int node, int high) { for (int level = LOG - 1; level >= 0; level--) { if (depth[parent[node][level]] >= high) { node = parent[node][level]; } } return node; } void dp(int node) { sumF[node] = 0; for (auto &u : adj[node]) { if (u != parent[node][0]) { dp(u); sumF[node] += f[u]; } } f[node] = sumF[node]; for (auto &index : planAt[node]) { int u = plans[index].u, v = plans[index].v; int pu = jump(u, depth[node] + 1), pv = jump(v, depth[node] + 1); int tmp = sumF[node]; if (u != node){ tmp += smt.get(start[u]) - f[pu]; } if (v != node) { tmp += smt.get(start[v]) - f[pv]; } f[node] = max(f[node], tmp + plans[index].cost); } for (auto &u : adj[node]) { if (u != parent[node][0]) { smt.update(start[u], stop[u], sumF[node] - f[u]); } } smt.update(start[node], start[node], sumF[node]); } int main() { ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0); #ifdef Flower_On_Stone freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout); #endif // Flower_On_Stone cin >> numCity; for (int i = 1; i < numCity; i++) { int u, v; cin >> u >> v; adj[u].push_back(v); adj[v].push_back(u); } cin >> numPLan; for (int i = 1; i <= numPLan; i++) { cin >> plans[i].u >> plans[i].v >> plans[i].cost; } depth[0] = -1; id = 0; dfs(1); smt.init(numCity); for (int i = 1; i <= numPLan; i++) { planAt[lca(plans[i].u, plans[i].v)].push_back(i); } dp(1); cout << f[1]; return 0; }
#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...