QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#18333 | #2214. Link Cut Digraph | Komeiji | RE | 0ms | 0kb | C++20 | 2.7kb | 2022-01-17 21:26:55 | 2022-05-04 17:58:30 |
Judging History
answer
#include <bits/stdc++.h>
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout.tie(nullptr);
int n, m;
std::cin >> n >> m;
std::vector<std::pair<int, int>> edges;
std::vector<int> f(n + 1), vis(n + 1), ans(n + 1), dfn(n + 1), low(n + 1), scc(n + 1), ins(n + 1), siz(n + 1, 1);
std::iota(f.begin(), f.end(), 0);
std::stack<int> stack;
int curt = 0, dfnt = 0, stot = 0;
for (int i = 0; i < m; ++i) {
int x, y;
std::cin >> x >> y;
edges.emplace_back(x, y);
}
auto find = [&](int x) {
while (x != f[x])
x = f[x] = f[f[x]];
return x;
};
std::vector<std::vector<int>> G(n + 1, std::vector<int>());
std::function<void(int)> tarjan = [&](int x) {
low[x] = dfn[x] = ++dfnt;
stack.emplace(x);
ins[x] = true;
for (int y : G[x]) {
if (!dfn[y]) {
tarjan(y);
low[x] = std::min(low[x], low[y]);
}
else if (ins[y]) {
low[x] = std::min(low[x], dfn[y]);
}
}
if (dfn[x] == low[x]) {
++stot;
int y;
do {
y = stack.top(); stack.pop();
ins[y] = false;
scc[y] = stot;
} while (y != x);
}
};
std::function<void(int, int, std::vector<int>)> solve = [&](int l, int r, std::vector<int> eids) {
const int mid = l + r >> 1;
++curt;
std::vector<int> nodes;
auto push = [&](int x) {
if (vis[x] != curt) {
vis[x] = curt;
nodes.push_back(x);
}
};
for (int o : eids) {
if (o <= mid) {
auto [x, y] = edges[o];
int _x = x, _y = y;
x = find(x), y = find(y);
push(x), push(y);
if (x != y) {
G[x].push_back(y);
}
}
}
for (int x : nodes)
assert(!dfn[x]);
for (int x : nodes)
if (!dfn[x])
tarjan(x);
if (l == r) {
if (l) ans[l] = ans[l - 1];
for (int o: eids) {
auto [x, y] = edges[o];
if (find(x) != find(y) && scc[find(x)] == scc[find(y)]) {
int _x = x, _y = y;
x = find(x);
y = find(y);
ans[l] += 1ll * siz[x] * siz[y];
siz[y] += siz[x], siz[x] = 0;
f[x] = y;
}
}
for (int x : nodes) G[x].clear(), dfn[x] = low[x] = ins[x] = scc[x] = 0;
dfnt = stot = 0;
while (!stack.empty())
stack.pop();
}
else {
std::vector<int> le, ri;
for (int o : eids) {
auto [x, y] = edges[o];
if (find(x) == find(y)) continue;
if (o <= mid && scc[find(x)] == scc[find(y)]) {
le.push_back(o);
}
else {
ri.push_back(o);
}
}
for (int x : nodes) G[x].clear(), dfn[x] = low[x] = ins[x] = scc[x] = 0;
dfnt = stot = 0;
while (!stack.empty())
stack.pop();
solve(l, mid, le);
solve(mid + 1, r, ri);
}
};
std::vector<int> eids(m);
std::iota(eids.begin(), eids.end(), 0);
solve(0, m - 1, eids);
for (int i = 0; i < m; ++i)
std::cout << ans[i] << '\n';
return 0;
}
Details
Test #1:
score: 0
Runtime Error