답안 #1060326

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
1060326 2024-08-15T12:59:36 Z nima_aryan 조이터에서 친구를 만드는건 재밌어 (JOI20_joitter2) C++17
0 / 100
5000 ms 14940 KB
/**
 *    author:  NimaAryan
 *    created: 2024-08-15 13:30:23
**/
#include <bits/stdc++.h>

using namespace std;

#ifdef LOCAL
#include "algo/debug.h"
#endif

using i64 = long long;

constexpr int N = 1E5;

i64 ans = 0;
vector<set<int>> S(N);  // all vertices in A
vector<set<int>> T(N);  // {x->a | a \in A}
vector<set<int>> G(N);  // {B | a \in A, a->B}
vector<int> par(N, -1);
vector<pair<int, int>> to_merge;

int find(int x) {
  return par[x] == -1 ? x : par[x] = find(par[x]);
}

int size(int A) {
  return S[A].size() + T[A].size() + G[A].size();
}

void unite(int A, int B) {
  A = find(A), B = find(B);

  if (A == B) {
    return;
  }

  if (size(A) < size(B)) {
    swap(A, B);
  }

  ans -= 1LL * S[A].size() * (S[A].size() - 1);
  ans -= 1LL * S[A].size() * T[A].size();
  ans -= 1LL * S[B].size() * (S[B].size() - 1);
  ans -= 1LL * S[B].size() * T[B].size();

  G[A].erase(B);
  for (int X : G[B]) {
    if (X == A) {
      continue;
    }
    if (G[X].count(A)) {
      to_merge.emplace_back(A, X);
    }
    G[A].insert(X);
  }
  for (int x : T[B]) {
    int X = find(x);
    if (X == A) {
      continue;
    }
    T[A].insert(x);
    if (G[A].count(X)) {
      to_merge.emplace_back(A, X);
    }
    G[X].erase(B);
    G[X].insert(A);
  }
  for (int b : S[B]) {
    T[A].erase(b);
    S[A].insert(b);
  }
  par[B] = A;

  ans += 1LL * S[A].size() * (S[A].size() - 1);
  ans += 1LL * S[A].size() * T[A].size();
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);

  int n, m;
  cin >> n >> m;

  for (int x = 0; x < n; ++x) {
    S[x] = {x};
  }

  while (m--) {
    int a, b;
    cin >> a >> b;
    --a, --b;

    int A = find(a), B = find(b);
    if (A != B) {
      if (G[B].count(A)) {
        unite(A, B);
      } else if (!T[B].count(a)) {
        ans += S[B].size();
        T[B].insert(a);
        G[A].insert(B);
      }
      while (!to_merge.empty()) {
        auto [X, Y] = to_merge.back();
        to_merge.back();
        unite(X, Y);
      }
    }

    cout << ans << "\n";
  }

  return 0;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 4 ms 14936 KB Output is correct
2 Correct 4 ms 14940 KB Output is correct
3 Execution timed out 5075 ms 14940 KB Time limit exceeded
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 4 ms 14936 KB Output is correct
2 Correct 4 ms 14940 KB Output is correct
3 Execution timed out 5075 ms 14940 KB Time limit exceeded
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 4 ms 14936 KB Output is correct
2 Correct 4 ms 14940 KB Output is correct
3 Execution timed out 5075 ms 14940 KB Time limit exceeded
4 Halted 0 ms 0 KB -