제출 #251487

#제출 시각아이디문제언어결과실행 시간메모리
251487imeimi2000조이터에서 친구를 만드는건 재밌어 (JOI20_joitter2)C++17
100 / 100
775 ms49272 KiB
#include <bits/stdc++.h>

using namespace std;
typedef pair<int, int> pii;

int n;
int G[100001];
vector<int> L[100001];
set<pii> in[100001], out[100001];
int size(int x) {
    return L[x].size() + in[x].size() + out[x].size();
}

bool exist(const set<pii> &sp, int g) {
    auto it = sp.lower_bound(pii(g, 0));
    return it != sp.end() && it->first == g;
}

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0);
    int m;
    cin >> n >> m;
    for (int i = 1; i <= n; ++i) G[i] = i, L[i].push_back(i);
    long long cnt = 0;
    while (m--) {
        int a, b;
        cin >> a >> b;
        if (G[a] == G[b] || in[G[b]].count(pii(G[a], a))) {
            printf("%lld\n", cnt);
            continue;
        }
        cnt += L[G[b]].size();
        in[G[b]].emplace(G[a], a);
        out[G[a]].emplace(G[b], a);
        vector<pii> V;
        if (exist(in[G[a]], G[b])) V.emplace_back(a, b);
        while (!V.empty()) {
            auto [a, b] = V.back();
            V.pop_back();
            a = G[a], b = G[b];
            if (a == b) continue;
            if (size(a) < size(b)) swap(a, b);
            int sa = L[a].size(), sb = L[b].size();
            cnt += (2ll * sa + int(in[a].size())) * sb;
            for (int i : L[b]) {
                G[i] = a;
                L[a].push_back(i);
            }
            L[b].clear();
            for (auto [g, i] : in[b]) {
                out[g].erase(pii(b, i));
                if (g == a) {
                    cnt -= sb;
                }
                else if (in[a].count(pii(g, i))) {
                    cnt -= sb;
                    continue;
                }
                else {
                    if (exist(out[a], g)) V.emplace_back(a, g);
                    cnt += sa;
                    out[g].emplace(a, i);
                    in[a].emplace(g, i);
                }
            }
            in[b].clear();
            for (auto [g, i] : out[b]) {
                in[g].erase(pii(b, i));
                if (g == a) {
                    cnt -= sa + sb;
                }
                else {
                    if (exist(in[a], g)) V.emplace_back(a, g);
                    in[g].emplace(a, i);
                    out[a].emplace(g, i);
                }
            }
            out[b].clear();
        }
        printf("%lld\n", cnt);
    }
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...