Submission #657630

#TimeUsernameProblemLanguageResultExecution timeMemory
657630tamthegodElection Campaign (JOI15_election_campaign)C++17
100 / 100
504 ms41976 KiB
// Make the best become better // No room for laziness #include<bits/stdc++.h> #define int long long #define pb push_back #define fi first #define se second using namespace std; using ll = long long; using ld = long double; using ull = unsigned long long; mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); const int maxN = 1e5 + 5; const int mod = 1e9 + 7; const ll oo = 1e18; int n, m; vector<int> adj[maxN]; struct TPath { int s, t, w; } a[maxN]; int sz[maxN], p[maxN], depth[maxN]; int chainhead[maxN], chainid[maxN], nChain = 0; int timein[maxN], Time = 0; vector<TPath> vc[maxN]; int f[maxN]; struct SegTree { int st[4 * maxN]; void Init() { memset(st, 0, sizeof st); } void update(int id, int l, int r, int pos, int val) { if(l > pos || r < pos) return; if(l == r && l == pos) { st[id] += val; return; } int mid = (l + r) / 2; update(id * 2, l, mid, pos, val); update(id * 2 + 1, mid + 1, r, pos, val); st[id] = st[id * 2] + st[id * 2 + 1]; } int get(int id, int l, int r, int u, int v) { if(l > v || r < u) return 0; if(l >= u && r <= v) return st[id]; int mid = (l + r) / 2; return get(id * 2, l, mid, u, v) + get(id * 2 + 1, mid + 1, r, u, v); } } tree1, tree2; void dfs(int u) { sz[u] = 1; for(int v : adj[u]) { if(v == p[u]) continue; p[v] = u; depth[v] = depth[u] + 1; dfs(v); sz[u] += sz[v]; } } void HLD(int u) { if(!chainhead[nChain]) chainhead[nChain] = u; chainid[u] = nChain; timein[u] = ++Time; int bigChild = -1; for(int v : adj[u]) { if(v == p[u]) continue; if(bigChild == -1 || sz[bigChild] < sz[v]) bigChild = v; } if(bigChild != -1) HLD(bigChild); for(int v : adj[u]) { if(v == p[u] || v == bigChild) continue; nChain++; HLD(v); } } int LCA(int u, int v) { while(chainhead[chainid[u]] != chainhead[chainid[v]]) { if(depth[chainhead[chainid[u]]] < depth[chainhead[chainid[v]]]) swap(u, v); u = p[chainhead[chainid[u]]]; } if(depth[u] > depth[v]) swap(u, v); return u; } int Query(int u, int v) { int res = 0; while(chainhead[chainid[u]] != chainhead[chainid[v]]) { if(depth[chainhead[chainid[u]]] < depth[chainhead[chainid[v]]]) swap(u, v); res += tree1.get(1, 1, n, timein[chainhead[chainid[u]]], timein[u]); u = p[chainhead[chainid[u]]]; } if(depth[u] > depth[v]) swap(u, v); res += tree1.get(1, 1, n, timein[u], timein[v]); return res; } int Query1(int u, int v) { int res = 0; while(chainhead[chainid[u]] != chainhead[chainid[v]]) { if(depth[chainhead[chainid[u]]] < depth[chainhead[chainid[v]]]) swap(u, v); res += tree2.get(1, 1, n, timein[chainhead[chainid[u]]], timein[u]); u = p[chainhead[chainid[u]]]; } if(depth[u] > depth[v]) swap(u, v); res += tree2.get(1, 1, n, timein[u], timein[v]); return res; } void ReadInput() { cin >> n; for(int i=1; i<n; i++) { int u, v; cin >> u >> v; adj[u].pb(v); adj[v].pb(u); } cin >> m; for(int i=1; i<=m; i++) { cin >> a[i].s >> a[i].t >> a[i].w; } } void DFS(int u) { int sum = 0; for(int v : adj[u]) { if(v == p[u]) continue; DFS(v); sum += f[v]; } f[u] = sum; for(int v : adj[u]) { if(v == p[u]) continue; tree1.update(1, 1, n, timein[u], f[v]); } for(TPath a : vc[u]) { f[u] = max(f[u], Query(a.s, a.t) - Query1(a.s, a.t) + a.w); } tree2.update(1, 1, n, timein[u], f[u]); } void Solve() { dfs(1); HLD(1); tree1.Init(); tree2.Init(); for(int i=1; i<=m; i++) vc[LCA(a[i].s, a[i].t)].pb(a[i]); DFS(1); cout << f[1]; } int32_t main() { //freopen("x.inp", "r", stdin); ios_base::sync_with_stdio(false); cin.tie(nullptr); ReadInput(); Solve(); }
#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...