QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#555805 | #2214. Link Cut Digraph | etohari | WA | 395ms | 72084kb | C++20 | 3.3kb | 2024-09-10 10:09:30 | 2024-09-10 10:09:30 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
namespace std {
#ifndef LOCAL
#define cerr \
if (0) cerr
#endif
} // namespace std
struct DSU {
vector<int> par;
int64_t cur_ans;
DSU(int n = 0) {
par.assign(n + 5, -1);
cur_ans = 0;
}
int root(int u) {
if (par[u] < 0)
return u;
return par[u] = root(par[u]);
}
int size(int u) {
return -par[root(u)];
}
bool join(int u, int v) {
u = root(u);
v = root(v);
if (u == v)
return false;
cur_ans += 1ll * -par[u] * -par[v];
if (par[u] > par[v])
swap(u, v);
par[u] += par[v];
par[v] = u;
return true;
}
};
const int N = 2.5e5 + 5;
int n, m;
pair<int, int> ed[N];
DSU dsu(N);
int64_t ans[N];
vector<int> nodes;
vector<int> g[N];
int low[N], num[N], time_dfs, del[N];
int id_scc[N];
vector<int> stk;
vector<vector<int>> scc;
vector<int> T[N];
void dfs(int u) {
low[u] = num[u] = ++time_dfs;
stk.push_back(u);
for (int v : g[u]) {
if (del[v]) {
continue;
}
if (!num[v]) {
dfs(v);
low[u] = min(low[u], low[v]);
} else {
low[u] = min(low[u], num[v]);
}
}
if (low[u] == num[u]) {
scc.push_back({});
int v;
do {
v = stk.back();
scc.back().push_back(v);
id_scc[v] = scc.size();
del[v] = 1;
stk.pop_back();
} while (v != u);
}
}
void add_edge(int u, int v) {
nodes.push_back(u);
nodes.push_back(v);
g[u].push_back(v);
}
void reset() {
for (int u : nodes) {
low[u] = num[u] = del[u] = 0;
id_scc[u] = 0;
g[u].clear();
}
nodes.clear();
stk.clear();
scc.clear();
time_dfs = 0;
}
void solve(int l, int r, vector<int> edges) {
if (l > r) {
return;
}
int mid = (l + r) >> 1;
reset();
for (int i : edges) {
if (i <= mid) {
auto [x, y] = ed[i];
x = dsu.root(x);
y = dsu.root(y);
add_edge(x, y);
}
}
for (int u : nodes) {
if (!num[u]) {
dfs(u);
}
}
vector<vector<int>> cur_scc = scc;
vector<int> g1, g2;
for (int i : edges) {
if (i <= mid) {
auto [u, v] = ed[i];
u = dsu.root(u), v = dsu.root(v);
if (id_scc[u] == id_scc[v]) {
T[mid].push_back(i);
g1.push_back(i);
} else {
g2.push_back(i);
}
} else {
g2.push_back(i);
}
}
solve(l, mid - 1, g1);
solve(mid + 1, r, g2);
for (int i : g1) {
dsu.join(ed[i].first, ed[i].second);
}
// for (auto v : cur_scc) {
// for (auto i : v) {
// dsu.join(i, v.front());
// }
// }
edges.clear();
g1.clear();
g2.clear();
}
int32_t main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
#ifdef LOCAL
#define task "a"
#else
#define task ""
#endif
if (fopen(task ".inp", "r")) {
freopen(task ".inp", "r", stdin);
freopen(task ".out", "w", stdout);
}
cin >> n >> m;
for (int i = 1; i <= m; i++) {
auto& [u, v] = ed[i];
cin >> u >> v;
}
vector<int> id(m);
iota(id.begin(), id.end(), 1);
solve(1, m, id);
dsu = DSU(n);
for (int i = 1; i <= m; i++) {
for (auto id : T[i]) {
dsu.join(ed[id].first, ed[id].second);
}
cout << dsu.cur_ans << "\n";
}
return 0;
}
Details
Test #1:
score: 0
Wrong Answer
time: 395ms
memory: 72084kb