QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#491231#2214. Link Cut DigraphnaiijAC ✓953ms52004kbC++204.0kb2024-07-25 17:55:092024-07-25 17:55:13

Judging History

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

  • [2024-07-25 17:55:13]
  • 评测
  • 测评结果:AC
  • 用时:953ms
  • 内存:52004kb
  • [2024-07-25 17:55:09]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

struct DSU {
    vector<int> f, size;
    DSU() {}
    DSU(int n) : f(n) {
        iota(f.begin(), f.end(), 0);
        size.assign(n, 1);
    }
    int find(int x) {
        while (x != f[x]) x = f[x] = f[f[x]];
        return x;
    }

    void merge(int x, int y) {
        x = find(x);
        y = find(y);
        if (x == y) return;
        if (size[x] < size[y]) swap(x, y);
        f[y] = x;
        size[x] += size[y];
    }
};

struct Graph {
    vector<vector<int> > adj;
    vector<int> idx, low, color;
    vector<bool> in_stack;

    Graph() {}
    Graph(int n) {
        init(n);
    }

    void init(int n) {
        adj.assign(n, vector<int>());
        idx.assign(n, 0);
        low.assign(n, 0);
        in_stack.assign(n, false);
        color.assign(n, -1);
    }

    void add_edge(int u, int v) {
        adj[u].push_back(v);
    }

    void dfs(int u);

    bool vis(int u) {
        return idx[u] > 0;
    }
};

void Graph::dfs(int u) {
    static int tot = 0;
    static stack<int> st;
    idx[u] = low[u] = ++tot;
    st.push(u);
    in_stack[u] = true;
    for (int v : adj[u]) {
        if (idx[v] == 0) {
            dfs(v);
            low[u] = min(low[u], low[v]);
        } else if (in_stack[v]) {
            low[u] = min(low[u], idx[v]);
        }
    }
    if (idx[u] == low[u]) {
        int v;
        static int clr = 0;
        do {
            v = st.top();
            st.pop();
            in_stack[v] = false;
            color[v] = clr;
        } while (v != u);
        ++clr;
    }
}

int main() {
    ios::sync_with_stdio(0);
    int n, m;
    cin >> n >> m;
    DSU dsu(n);
    vector<pair<int, int> > edges;
    for (int i = 0, u, v; i < m; i++) {
        cin >> u >> v;
        --u;
        --v;
        edges.push_back({u, v});
    }
    ll ans = 0;
    auto solve = [&](auto &&self, int l, int r, vector<int> E) -> void {
        // if (l == r) {
        //     cout << "###### Time: " << l << "\n";
        //     for (int i : E) {
        //         auto [x, y] = edges[i];
        //         cout << x << ' ' << y << '\n';
        //     }
        // }
        unordered_map<int, int> mp;
        int N = 0;
        for (int i : E) {
            if (i > r) continue;
            auto [x, y] = edges[i];
            x = dsu.find(x);
            y = dsu.find(y);
            if (x == y) continue;
            if (!mp.count(x)) mp[x] = N++;
            if (!mp.count(y)) mp[y] = N++;
        }
        Graph g(N);
        for (int i : E) {
            if (i > r) continue;
            auto [x, y] = edges[i];
            x = dsu.find(x);
            y = dsu.find(y);
            if (x == y) continue;
            g.add_edge(mp[x], mp[y]);
        }
        for (int i = 0; i < N; i++) {
            if (!g.vis(i)) g.dfs(i);
        }
        vector<int> nE;
        for (int i : E) {
            if (i > r) continue;
            auto [x, y] = edges[i];
            x = dsu.find(x);
            y = dsu.find(y);
            if (x == y) continue;
            if (g.color[mp[x]] == g.color[mp[y]]) {
                // nE 这个边集令 (x,y) 在 [l,r] 内连通
                nE.push_back(i);
            }
        }
        if (l == r) {
            for (int i : nE) {
                auto [x, y] = edges[i];
                x = dsu.find(x);
                y = dsu.find(y);
                if (x == y) continue;
                // i 这条边对答案的贡献: 令 size(x) * size(y) 个 pairs 连通
                ans += 1ll * dsu.size[x] * dsu.size[y];
                dsu.merge(x, y);
            }
            cout << ans << '\n';
            return;
        }
        int mid = (l + r) >> 1;
        self(self, l, mid, nE);
        self(self, mid + 1, r, nE);
    };
    vector<int> E(m);
    iota(E.begin(), E.end(), 0);
    solve(solve, 0, m - 1, E);
    return 0;
}

Details

Test #1:

score: 100
Accepted
time: 953ms
memory: 52004kb

Test #2:

score: 0
Accepted
time: 912ms
memory: 51660kb

Test #3:

score: 0
Accepted
time: 944ms
memory: 51628kb

Test #4:

score: 0
Accepted
time: 664ms
memory: 35092kb

Test #5:

score: 0
Accepted
time: 927ms
memory: 51328kb

Test #6:

score: 0
Accepted
time: 946ms
memory: 51216kb

Test #7:

score: 0
Accepted
time: 940ms
memory: 51916kb

Test #8:

score: 0
Accepted
time: 943ms
memory: 51752kb

Test #9:

score: 0
Accepted
time: 395ms
memory: 29492kb

Test #10:

score: 0
Accepted
time: 929ms
memory: 51500kb

Test #11:

score: 0
Accepted
time: 951ms
memory: 51048kb

Test #12:

score: 0
Accepted
time: 941ms
memory: 51368kb

Test #13:

score: 0
Accepted
time: 399ms
memory: 29592kb

Test #14:

score: 0
Accepted
time: 401ms
memory: 29920kb

Test #15:

score: 0
Accepted
time: 185ms
memory: 22924kb

Test #16:

score: 0
Accepted
time: 877ms
memory: 41680kb

Test #17:

score: 0
Accepted
time: 879ms
memory: 41396kb

Test #18:

score: 0
Accepted
time: 872ms
memory: 41800kb

Test #19:

score: 0
Accepted
time: 941ms
memory: 51472kb

Test #20:

score: 0
Accepted
time: 716ms
memory: 34088kb

Test #21:

score: 0
Accepted
time: 726ms
memory: 34144kb

Test #22:

score: 0
Accepted
time: 721ms
memory: 34260kb

Test #23:

score: 0
Accepted
time: 728ms
memory: 34312kb

Test #24:

score: 0
Accepted
time: 726ms
memory: 34176kb

Test #25:

score: 0
Accepted
time: 693ms
memory: 33720kb

Test #26:

score: 0
Accepted
time: 699ms
memory: 34268kb

Test #27:

score: 0
Accepted
time: 754ms
memory: 34604kb