QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#74500 | #2214. Link Cut Digraph | elkernos | ML | 0ms | 0kb | C++20 | 2.7kb | 2023-02-02 00:45:11 | 2023-02-02 00:45:13 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
const int nax = 100007;
struct scc {
vector<int> graf[nax], farg[nax];
vector<int> cur;
vector<int> topo;
int comp[nax], iter;
bitset<nax> vis;
void czysc()
{
for (auto x : cur)
graf[x].clear(), farg[x].clear();
cur.clear();
}
void add(int a, int b)
{
graf[a].emplace_back(b), farg[b].emplace_back(a);
cur.emplace_back(a), cur.emplace_back(b);
}
void dfs_one(int x)
{
vis[x] = 1;
for (auto to : graf[x])
if (!vis[to]) dfs_one(to);
topo.emplace_back(x);
}
void dfs_two(int x)
{
comp[x] = iter;
for (auto to : farg[x])
if (!comp[to]) dfs_two(to);
}
void work()
{
topo.clear();
for (auto x : cur)
comp[x] = vis[x] = 0;
iter = 1;
for (auto x : cur)
if (!vis[x]) dfs_one(x);
reverse(topo.begin(), topo.end());
for (auto x : topo)
if (!comp[x]) dfs_two(x), iter++;
}
} scc;
long long po2(int x) { return (long long)x * (x - 1) / 2; }
struct dsu {
int par[nax], sz[nax];
long long xd;
dsu()
{
iota(par + 1, par + nax, 1);
fill(sz + 1, sz + nax, 1);
xd = 0;
}
int find(int x) { return par[x] == x ? x : par[x] = find(par[x]); }
bool uni(int a, int b)
{
a = find(a), b = find(b);
if (a == b) return 0;
xd = xd - po2(sz[a]) - po2(sz[b]);
if (sz[a] < sz[b]) swap(a, b);
par[b] = a;
sz[a] += sz[b];
xd = xd + po2(sz[a]);
return 1;
}
} dsu;
array<int, 2> edges[nax];
long long ans[nax];
void rek(int a, int b, vector<int> &ord)
{
if (a == b) {
for (auto i : ord)
dsu.uni(edges[i][0], edges[i][1]);
ans[a] = dsu.xd;
return;
}
int m = (a + b) / 2;
scc.czysc();
for (auto i : ord)
if (i <= m) scc.add(dsu.find(edges[i][0]), dsu.find(edges[i][1]));
scc.work();
vector<int> l, r;
for (auto i : ord) {
if (i > m) {
r.emplace_back(i);
continue;
}
if (scc.comp[dsu.find(edges[i][0])] == scc.comp[dsu.find(edges[i][1])]) l.emplace_back(i);
else r.emplace_back(i);
}
rek(a, m, l), rek(m + 1, b, r);
}
int main()
{
cin.tie(0)->sync_with_stdio(0);
int n, m;
cin >> n >> m;
for (int i = 1; i <= m; i++)
cin >> edges[i][0] >> edges[i][1];
vector<int> ord(m);
iota(ord.begin(), ord.end(), 1);
rek(1, m + 1, ord);
for (int i = 1; i <= m; i++)
cout << ans[i] << "\n";
}
详细
Test #1:
score: 0
Memory Limit Exceeded