QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#74498#2214. Link Cut DigraphelkernosML 0ms0kbC++202.7kb2023-02-02 00:42:472023-02-02 00:42:48

Judging History

你现在查看的是最新测评结果

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-02-02 00:42:48]
  • 评测
  • 测评结果:ML
  • 用时:0ms
  • 内存:0kb
  • [2023-02-02 00:42:47]
  • 提交

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