Submission #1082569

#TimeUsernameProblemLanguageResultExecution timeMemory
1082569WhisperRoadside Advertisements (NOI17_roadsideadverts)C++17
100 / 100
50 ms26708 KiB
#include <bits/stdc++.h> using namespace std; using ll = long long; #define int long long #define FOR(i, a, b) for (int i = (a); i <= (b); i++) #define FORD(i, a, b) for (int i = (b); i >= (a); i --) #define REP(i, a) for (int i = 0; i < (a); ++i) #define REPD(i, a) for (int i = (a) - 1; i >= 0; --i) #define MASK(i) (1LL << (i)) #define BIT(x, i) (((x) >> (i)) & 1) constexpr ll LINF = (1ll << 60); constexpr int INF = (1ll << 30); constexpr int Mod = 1e9 + 7; mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); /* Phu Trong from Nguyen Tat Thanh High School for gifted student */ template <class X, class Y> bool minimize(X &x, const Y &y){ X eps = 1e-9; if (x > y + eps) {x = y; return 1;} return 0; } template <class X, class Y> bool maximize(X &x, const Y &y){ X eps = 1e-9; if (x + eps < y) {x = y; return 1;} return 0; } #define MIN_HIGH(u, v) (depth[u] < depth[v] ? (u) : (v)) #define LOG 20 #define MAX 50005 int numNode, numQuery; struct Edge{ int u, v, w; Edge(){} Edge(int _u, int _v, int _w): u(_u), v(_v), w(_w){} int other(int x){ return (x ^ u ^ v); } } edge[MAX]; vector<int> G[MAX]; namespace DistanceOnTree{ int tin[MAX], timeDfs = 0, rev[MAX]; int cnt = 0, st[MAX << 1][20], pos[MAX << 1], d[MAX], depth[MAX]; void pre_dfs(int u, int p = -1){ tin[u] = ++timeDfs; rev[timeDfs] = u; st[++cnt][0] = u; pos[u] = cnt; for (int&i : G[u]){ int v = edge[i].other(u); if(v ^ p){ depth[v] = depth[u] + 1; d[v] = d[u] + edge[i].w; pre_dfs(v, u); st[++cnt][0] = u; } } } void build(void){ pre_dfs(1); for (int i = 1; MASK(i) <= cnt; ++i){ for (int u = 1; u + MASK(i) - 1 <= cnt; ++u){ st[u][i] = MIN_HIGH(st[u][i - 1], st[u + MASK(i - 1)][i - 1]); } } } int lca(int u, int v){ int l = pos[u], r = pos[v]; if(l > r) swap(l, r); int k = 31 - __builtin_clz(r - l + 1); return MIN_HIGH(st[l][k], st[r - MASK(k) + 1][k]); } set<int> mySet; int sum = 0; int dis(int u, int v){ return d[u] + d[v] - 2 * d[lca(u, v)]; } void ins(int x){ x = tin[x]; if(mySet.empty()){ mySet.insert(x); return; } if(mySet.size() == 1){ sum += 2 * dis(rev[*mySet.begin()], rev[x]); mySet.insert(x); return; } auto it = mySet.lower_bound(x); int l = -1, r = -1; if(it == mySet.begin() || it == mySet.end()){ l = rev[*mySet.begin()]; r = rev[*prev(mySet.end())]; } else{ l = rev[*prev(it)]; r = rev[*it]; } assert(l != -1); assert(r != -1); mySet.insert(x); sum += dis(l, rev[x]); sum += dis(r, rev[x]); sum -= dis(l, r); } void eras(int x){ x = tin[x]; mySet.erase(x); if(mySet.size() == 0){ sum = 0; return; } if(mySet.size() == 1){ sum -= 2 * dis(rev[x], rev[*mySet.begin()]); return; } int l = -1, r = -1; auto it = mySet.lower_bound(x); if(it == mySet.begin() || it == mySet.end()){ l = rev[*mySet.begin()]; r = rev[*prev(mySet.end())]; } else{ l = rev[*prev(it)]; r = rev[*it]; } sum += dis(l, r); sum -= dis(l, rev[x]); sum -= dis(r, rev[x]); } int ans(void){ return sum / 2; } } #define T DistanceOnTree void process(void){ cin >> numNode; for (int i = 1; i < numNode; ++i){ cin >> edge[i].u >> edge[i].v >> edge[i].w; ++edge[i].u, ++edge[i].v; G[edge[i].u].emplace_back(i); G[edge[i].v].emplace_back(i); } T :: build(); cin >> numQuery; for (int i = 1; i <= numQuery; ++i){ int node[5]; REP(j, 5) { cin >> node[j]; ++node[j]; T :: ins(node[j]); } cout << T :: ans() << '\n'; REP(j, 5){ T :: eras(node[j]); } } } signed main(){ #define name "Whisper" cin.tie(nullptr) -> sync_with_stdio(false); //freopen(name".inp", "r", stdin); //freopen(name".out", "w", stdout); process(); return (0 ^ 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...