답안 #1070606

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
1070606 2024-08-22T15:56:48 Z TraianDanciu 조이터에서 친구를 만드는건 재밌어 (JOI20_joitter2) C++17
0 / 100
2 ms 11612 KB
#include <stdio.h>
#include <set>

#define MAXN 100000
#define MAXM 300000

struct Edge {
  int u, v;
} edges[MAXM];
int sef1[MAXN], sef2[MAXN], sz[MAXN], stiva[MAXN], sp;
std::set<int> flw[MAXN], muchii[MAXN];
std::set<std::pair<int, int>> mp;
long long rez;

static inline long long getrez(int i) {
  return 1LL * sz[i] * flw[i].size();
}

int find1(int i) {
  if(i == sef1[i]) {
    return i;
  }
  return sef1[i] = find1(sef1[i]);
}
void join1(int i, int j) {
  std::set<int>::iterator it;

  if((i = find1(i)) != (j = find1(j))) {
    if(sz[i] > sz[j]) {
      std::swap(i, j);
    }

    rez -= getrez(i) + getrez(j);
    sz[j] += sz[i];
    sef1[i] = j;

    if(flw[j].size() < flw[i].size()) {
      std::swap(flw[i], flw[j]);
    }
    it = flw[i].begin();
    while(it != flw[i].end()) {
      flw[j].insert(*it);
      it++;
    }

    rez += getrez(j);
  }
}

int find2(int i) {
  if(i == sef2[i]) {
    return i;
  }
  return sef2[i] = find2(sef2[i]);
}
void join2(int i, int j) {
  std::set<int>::iterator it;

  if((i = find2(i)) != (j = find2(j))) {
    join1(i, j);

    if(muchii[j].size() < muchii[i].size()) {
      std::swap(muchii[i], muchii[j]);
    }
    it = muchii[i].begin();
    while(it != muchii[i].end()) {
      stiva[sp++] = *it;
      muchii[j].insert(*it);
      it++;
    }

    sef2[i] = j;
  }
}

int main() {
  int n, m, i, u, v;

  scanf("%d%d", &n, &m);
  for(i = 0; i < n; i++) {
    sef1[i] = sef2[i] = i;
    flw[i].insert(i);
    sz[i] = 1;
  }

  rez = n;
  for(i = 0; i < m; i++) {
    scanf("%d%d", &edges[i].u, &edges[i].v);

    u = --edges[i].u;
    v = find1(--edges[i].v);
    rez -= getrez(v);
    flw[v].insert(u);
    rez += getrez(v);

    stiva[sp++] = i;
    while(sp > 0) {
      sp--;
      muchii[u = find2(edges[stiva[sp]].u)].insert(stiva[sp]);
      muchii[v = find2(edges[stiva[sp]].v)].insert(stiva[sp]);

      mp.insert(std::make_pair(u, v));
      if(mp.count(std::make_pair(v, u))) {
        join2(u, v);
      }
    }

    printf("%lld\n", rez - n);
  }

  return 0;
}

Compilation message

joitter2.cpp: In function 'int main()':
joitter2.cpp:79:8: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   79 |   scanf("%d%d", &n, &m);
      |   ~~~~~^~~~~~~~~~~~~~~~
joitter2.cpp:88:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   88 |     scanf("%d%d", &edges[i].u, &edges[i].v);
      |     ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 11612 KB Output is correct
2 Incorrect 2 ms 11612 KB Output isn't correct
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 11612 KB Output is correct
2 Incorrect 2 ms 11612 KB Output isn't correct
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 11612 KB Output is correct
2 Incorrect 2 ms 11612 KB Output isn't correct
3 Halted 0 ms 0 KB -