QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#623055 | #2214. Link Cut Digraph | ucup-team1264 | AC ✓ | 187ms | 28612kb | C++20 | 3.9kb | 2024-10-09 09:53:28 | 2024-10-09 09:53:29 |
Judging History
answer
// https://www.youtube.com/watch?v=CrymicX875M
// Angel of mercy
// How did you move me
// Why am I on my feet again
#ifndef ONLINE_JUDGE
#include "templates/debug.hpp"
#else
#define debug(...)
#endif
#include <bits/stdc++.h>
using namespace std;
using i64 = int64_t;
using u64 = uint64_t;
// #define int i64
void offlineIncrementalScc(vector<array<int, 2>> edge_updates, int n, vector<vector<int>> &joins) {
int m = size(edge_updates);
vector<int> ids(n, -1);
vector<array<int, 3>> eds(m);
for (int t = 0; t < m; t++) {
auto [u, v] = edge_updates[t];
eds[t] = {u, v, t};
}
vector<vector<int>> adj(n);
vector<int> low(n, -1), dfn(n, -1), scc_id(n, -1);
vector<int> stk;
int time = 0, scc_num = 0;
function<void(int)> tarjan = [&](int u) {
dfn[u] = low[u] = time++;
int sz = stk.size();
stk.push_back(u);
for (int v : adj[u]) {
if (dfn[v] == -1) tarjan(v), low[u] = min(low[u], low[v]);
else low[u] = min(low[u], dfn[v]);
}
if (dfn[u] == low[u]) {
for (int i = sz; i < (int)stk.size(); i++) {
scc_id[stk[i]] = scc_num;
dfn[stk[i]] = n;
}
scc_num++;
stk.resize(sz);
}
};
auto dfs = [&](auto &&self, auto el, auto er, int tl,
int tr) {
if (tl == tr) {
for (auto it = el; it != er; it++) {
if (tl != -1) joins[tl].push_back(it->back());
}
return;
}
int mid = tl + (tr - tl) / 2;
for (auto it = el; it != er; it++) {
auto [u, v, t] = *it;
dfn[u] = dfn[v] = -1;
adj[u].clear(), adj[v].clear();
}
for (auto it = el; it != er; it++) {
auto [u, v, t] = *it;
if (t <= mid) adj[u].push_back(v);
}
time = scc_num = 0;
for (auto it = el; it != er; it++) {
auto [u, v, t] = *it;
if (dfn[u] == -1) tarjan(u);
if (dfn[v] == -1) tarjan(v);
}
auto split = partition(el, er, [&](const auto &ed) {
return scc_id[ed[0]] == scc_id[ed[1]];
});
for (auto it = split; it != er; it++) {
auto &[u, v, t] = *it;
u = scc_id[u], v = scc_id[v];
}
self(self, el, split, tl, mid);
self(self, split, er, mid + 1, tr);
};
// uses -1 as the lower bound to correctly handle self-edges
dfs(dfs, begin(eds), end(eds), -1, m);
}
class UnionFindSet {
vector<int> fa, sz;
public:
UnionFindSet(int n) : fa(n), sz(n, 1) {
for (int i = 0; i < n; i++) {
fa[i] = i;
}
}
int size(int x) { return sz[find(x)]; }
int find(int x) { return x == fa[x] ? x : fa[x] = find(fa[x]); }
int merge(int x, int y) {
x = find(x), y = find(y);
if (x == y) return 0;
if (sz[x] < sz[y]) swap(x, y);
fa[y] = x, sz[x] += sz[y];
return 1;
}
};
void solve() {
int n, m; cin >> n >> m;
vector<array<int, 2>> edge_updates(m);
for (int i = 0; i < m; i++) {
int u, v; cin >> u >> v;
edge_updates[i] = {u - 1, v - 1};
}
vector<vector<int>> joins(m + 1);
offlineIncrementalScc(edge_updates, n, joins);
UnionFindSet ufs(n);
i64 ans = 0;
for (int t = 0; t < m; t++) {
for (int e: joins[t]) {
auto [u, v] = edge_updates[e];
if (ufs.find(u) != ufs.find(v)) {
ans += i64(ufs.size(u)) * ufs.size(v);
ufs.merge(u, v);
}
}
cout << ans << '\n';
}
}
#undef int
// Make bold hypotheses and verify carefully
int main() {
cin.tie(nullptr);
ios::sync_with_stdio(false);
int t = 1;
// cin >> t;
while (t--) {
solve();
};
}
詳細信息
Test #1:
score: 100
Accepted
time: 182ms
memory: 28612kb
Test #2:
score: 0
Accepted
time: 180ms
memory: 28360kb
Test #3:
score: 0
Accepted
time: 184ms
memory: 28568kb
Test #4:
score: 0
Accepted
time: 163ms
memory: 27724kb
Test #5:
score: 0
Accepted
time: 186ms
memory: 28456kb
Test #6:
score: 0
Accepted
time: 176ms
memory: 28544kb
Test #7:
score: 0
Accepted
time: 177ms
memory: 28328kb
Test #8:
score: 0
Accepted
time: 187ms
memory: 28316kb
Test #9:
score: 0
Accepted
time: 161ms
memory: 26816kb
Test #10:
score: 0
Accepted
time: 178ms
memory: 28520kb
Test #11:
score: 0
Accepted
time: 176ms
memory: 28244kb
Test #12:
score: 0
Accepted
time: 180ms
memory: 28496kb
Test #13:
score: 0
Accepted
time: 159ms
memory: 26740kb
Test #14:
score: 0
Accepted
time: 169ms
memory: 26460kb
Test #15:
score: 0
Accepted
time: 90ms
memory: 23772kb
Test #16:
score: 0
Accepted
time: 168ms
memory: 27112kb
Test #17:
score: 0
Accepted
time: 158ms
memory: 26980kb
Test #18:
score: 0
Accepted
time: 169ms
memory: 26900kb
Test #19:
score: 0
Accepted
time: 167ms
memory: 28436kb
Test #20:
score: 0
Accepted
time: 184ms
memory: 27296kb
Test #21:
score: 0
Accepted
time: 179ms
memory: 27472kb
Test #22:
score: 0
Accepted
time: 173ms
memory: 27584kb
Test #23:
score: 0
Accepted
time: 175ms
memory: 27492kb
Test #24:
score: 0
Accepted
time: 171ms
memory: 27488kb
Test #25:
score: 0
Accepted
time: 174ms
memory: 27400kb
Test #26:
score: 0
Accepted
time: 174ms
memory: 27332kb
Test #27:
score: 0
Accepted
time: 165ms
memory: 27416kb