Submission #1300327

#TimeUsernameProblemLanguageResultExecution timeMemory
1300327eyadoozMin-max tree (BOI18_minmaxtree)C++20
0 / 100
70 ms24984 KiB
#include <bits/stdc++.h> using namespace std; const int MAXN = 200005; vector<pair<int,int>> adj[MAXN]; int n, q; int parent[20][MAXN], depth[MAXN]; int parEdge[MAXN]; int edgeValue[MAXN]; int upEdge[20][MAXN]; void dfs(int u, int p, int pedge, int d){ parent[0][u] = p; depth[u] = d; parEdge[u] = pedge; for(auto &e: adj[u]){ int v=e.first, id=e.second; if(v==p) continue; dfs(v, u, id, d+1); } } int lca(int a,int b){ if(depth[a] < depth[b]) swap(a,b); int diff = depth[a] - depth[b]; for(int i=0;i<20;i++) if(diff & (1<<i)) a = parent[i][a]; if(a==b) return a; for(int i=19;i>=0;i--) if(parent[i][a] != parent[i][b]){ a = parent[i][a]; b = parent[i][b]; } return parent[0][a]; } void assign_on_path(int u, int anc, int val, bool isMin){ // isMin = true => all edges >= val // isMin = false => all edges <= val while(u != anc){ int id = parEdge[u]; if(isMin) edgeValue[id] = max(edgeValue[id], val); else edgeValue[id] = min(edgeValue[id], val); u = parent[0][u]; } } int main(){ ios::sync_with_stdio(false); cin.tie(nullptr); cin >> n; for(int i=0;i<n-1;i++){ int u,v; cin >> u >> v; adj[u].push_back({v,i}); adj[v].push_back({u,i}); edgeValue[i] = 0; // initial = 0 } dfs(1,0,-1,0); for(int i=1;i<20;i++) for(int u=1;u<=n;u++) parent[i][u] = parent[i-1][ parent[i-1][u] ]; cin >> q; struct Q { bool isMin; int u,v,z; }; vector<Q> queries; while(q--){ char c; int u,v,z; cin >> c >> u >> v >> z; queries.push_back({c=='m', u, v, z}); } // sort queries by z increasing sort(queries.begin(), queries.end(), [](auto &a, auto &b){ return a.z < b.z; }); // Apply constraints for(auto &qr : queries){ int u=qr.u, v=qr.v, z=qr.z; int w = lca(u,v); if(qr.isMin){ // path must have all edges >= z assign_on_path(u, w, z, true); assign_on_path(v, w, z, true); } else { // path must have all edges <= z if(edgeValue[ parEdge[w] ]); // ignore assign_on_path(u, w, z, false); assign_on_path(v, w, z, false); } } // Second pass: ensure at least one edge equals z for each query for(auto &qr: queries){ int u=qr.u, v=qr.v, z=qr.z; int w=lca(u,v); bool placed=false; // Try path u -> w int x=u; while(x!=w){ int id=parEdge[x]; if(edgeValue[id]==z){ placed=true; break; } x = parent[0][x]; } // Try path v -> w x=v; while(!placed && x!=w){ int id=parEdge[x]; if(edgeValue[id]==z){ placed=true; break; } x = parent[0][x]; } if(!placed){ // assign the first edge on the u→w path x=u; if(x!=w){ int id = parEdge[x]; edgeValue[id] = z; continue; } // otherwise assign first edge on v→w x=v; int id = parEdge[x]; edgeValue[id] = z; } } // Output for(int u=1;u<=n;u++){ for(auto &e: adj[u]){ int v=e.first, id=e.second; if(u < v){ cout << u << " " << v << " " << edgeValue[id] << "\n"; } } } 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...