Submission #652139

#TimeUsernameProblemLanguageResultExecution timeMemory
652139ymmPipes (CEOI15_pipes)C++17
90 / 100
2308 ms26628 KiB
#include <bits/stdc++.h> #define Loop(x,l,r) for (ll x = (l); x < (ll)(r); ++x) #define LoopR(x,l,r) for (ll x = (r)-1; x >= (ll)(l); --x) typedef long long ll; typedef std::pair<int, int> pii; typedef std::pair<ll , ll > pll; using namespace std; const int N = 100010; const int lg = 18; int sz[N]; int anc[N][lg]; int height[N]; struct edge_node { int v, e; int nxt; } pool[2*N]; int A[N]; int new_edge_node(int v, int e, int a) { static int nxt = 1; pool[nxt].v = v; pool[nxt].e = e; pool[nxt].nxt = a; return nxt++; } bool ans[N]; int buf[N]; vector<pii> edges; int nd[N]; int n, m; void dfs(int v) { height[v] = anc[v][0] >= 0? height[anc[v][0]]+1: 0; Loop (i,0,lg-1) anc[v][i+1] = anc[anc[v][i]][i]; nd[v] = A[v]; while (nd[v]) { if (pool[nd[v]].v != anc[v][0]) { anc[pool[nd[v]].v][0] = v; dfs(pool[nd[v]].v); } nd[v] = pool[nd[v]].nxt; } } int lca(int v, int u) { if (height[v] < height[u]) swap(v, u); int dif = height[v] - height[u]; Loop (i,0,lg) { if (dif & (1<<i)) v = anc[v][i]; } if (v == u) return v; LoopR (i,0,lg) { if (anc[v][i] != anc[u][i]) { v = anc[v][i]; u = anc[u][i]; } } return anc[v][0]; } int flush(int v) { nd[v] = A[v]; while (nd[v]) { if (pool[nd[v]].v != anc[v][0]) { auto tmp = flush(pool[nd[v]].v); ::ans[pool[nd[v]].e] |= tmp; buf[v] += tmp; } nd[v] = pool[nd[v]].nxt; } auto tmp = buf[v]; buf[v] = 0; return tmp; } int main() { cin.tie(0) -> sync_with_stdio(false); cin >> n >> m; Loop (i,0,n) { Loop (j,0,lg) anc[i][j] = i; sz[i] = 1; } Loop (i,0,m) { int v, u; cin >> v >> u; --v; --u; if (anc[v][lg-1] == anc[u][lg-1]) { buf[v] += 1; buf[u] += 1; buf[lca(v, u)] -= 2; } else { if (sz[anc[v][lg-1]] < sz[anc[u][lg-1]]) swap(v, u); flush(anc[u][lg-1]); A[v] = new_edge_node(u, edges.size(), A[v]); A[u] = new_edge_node(v, edges.size(), A[u]); edges.push_back({v, u}); sz[anc[v][lg-1]] += sz[anc[u][lg-1]]; anc[u][0] = v; dfs(u); } } Loop (i,0,n) if (anc[i][lg-1] == i) flush(i); Loop (i,0,edges.size()) { if (!ans[i]) { cout << edges[i].first+1 << ' '; cout << edges[i].second+1 << '\n'; } } }
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...