Submission #1197408

#TimeUsernameProblemLanguageResultExecution timeMemory
1197408Zero_OPReconstruction Project (JOI22_reconstruction)C++20
100 / 100
1216 ms19756 KiB
#include <bits/stdc++.h> using namespace std; struct DSU{ vector<int> lab; DSU(int n) : lab(n, -1) {} int root(int u){ return lab[u] < 0 ? u : (lab[u] = root(lab[u])); } bool join(int u, int v){ u = root(u); v = root(v); if(u == v) return false; if(lab[u] > lab[v]) swap(u, v); lab[u] += lab[v]; lab[v] = u; return true; } }; int main(){ ios_base::sync_with_stdio(0); cin.tie(0); #ifdef LOCAL freopen("task.inp", "r", stdin); freopen("task.out", "w", stdout); #endif //LOCAL int N, M; cin >> N >> M; vector<array<int, 3>> edges; for(int i = 0; i < M; ++i){ int u, v, w; cin >> u >> v >> w; --u, --v; edges.push_back({w, u, v}); } sort(edges.begin(), edges.end()); vector<int> par(N), depth(N); DSU dsu(N); vector<vector<int>> adj(N); function<void(int, int)> dfs = [&](int u, int e){ for(auto id : adj[u]) if(id != e){ int v = edges[id][1] ^ edges[id][2] ^ u; par[v] = id; depth[v] = depth[u] + 1; dfs(v, id); } }; function<void()> rebuild = [&](){ for(int i = 0; i < N; ++i) par[i] = -1, depth[i] = 0; for(int i = 0; i < N; ++i) if(depth[i] == 0) dfs(i, -1); }; vector<int> next(M, -1); vector<array<int, 3>> events; for(int i = 0; i < M; ++i){ int w = edges[i][0], u = edges[i][1], v = edges[i][2]; if(dsu.join(u, v)){ adj[u].emplace_back(i); adj[v].emplace_back(i); events.push_back({0, -1, w}); events.push_back({w, +1, -w}); events.push_back({w, +1, -w}); } else{ int remove_idx = -1; for(int pu = u, pv = v; pu != pv; ){ if(depth[pu] < depth[pv]) swap(pu, pv); int cur = par[pu]; if(remove_idx == -1 || edges[remove_idx][0] > edges[cur][0]){ remove_idx = cur; } pu ^= edges[cur][1] ^ edges[cur][2]; } next[remove_idx] = i; int a = edges[remove_idx][1], b = edges[remove_idx][2]; adj[a].erase(find(adj[a].begin(), adj[a].end(), remove_idx)); adj[b].erase(find(adj[b].begin(), adj[b].end(), remove_idx)); adj[u].push_back(i); adj[v].push_back(i); } rebuild(); } for(int i = 0; i < M; ++i){ if(next[i] != -1){ assert(i < next[i]); int p = (edges[i][0] + edges[next[i]][0] + 1) / 2; events.push_back({p, -1, +edges[i][0]}); events.push_back({p, -1, +edges[next[i]][0]}); events.push_back({edges[next[i]][0], +1, -edges[next[i]][0]}); events.push_back({edges[next[i]][0], +1, -edges[next[i]][0]}); } } sort(events.begin(), events.end()); // for(int i = 0; i < (int)events.size(); ++i){ // cout << events[i][0] << ' ' << events[i][1] << ' ' << events[i][2] << '\n'; // } int ptr = 0; long long a = 0, b = 0; //ax + b int Q; cin >> Q; while(Q--){ int X; cin >> X; // cout << "[" << X << "]\n"; while(ptr < (int)events.size() && events[ptr][0] <= X){ a += events[ptr][1]; b += events[ptr][2]; ++ptr; } // cout << a << ' ' << b << ' '; cout << a * X + b << '\n'; } return 0; } /* 4 5 1 2 4 1 4 3 2 4 2 2 3 1 3 4 3 4 1 2 3 4 */
#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...