Problem p02557 (C++) — buggy submission, verdict: Runtime Error

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

#define INF 1234567890
#define ll long long

int N;
int A[200201], AA[200201], BB[200201], F[200201];
vector<int> PA[200201];
int res[200201];
set<int> s[200201];

int main() {
  scanf("%d", &N);
  for (int i = 1; i <= N; i++) {
    scanf("%d", &A[i]);
    AA[A[i]]++;
    F[A[i]]++;
    PA[A[i]].push_back(i);
  }
  for (int i = 1; i <= N; i++) {
    int t;
    scanf("%d", &t);
    BB[t]++;
    F[t]++;
  }
  // 가능성 판별
  for (int i = 1; i <= N; i++)
    if (F[i] > N)
      return !printf("No");
  printf("Yes\\n");

  // 틀린 이유 : F[i]가 남아 있어도 AA[i]가 없을 수도 있다.
  for (int i = 1; i <= N; i++)
    if (AA[i])
      s[F[i]].insert(i); // s[cnt] = col

  // 아무 순서로나 소거하자. 최빈값이랑 매칭시키자.
  int p = N, q = N;
  for (int i = 1; i <= N; i++) {
    while (BB[i] > 0) {
      while (s[p].empty())
        p--;
      q = min(q, p);
      while (q && s[p].size() == 1 && (p == q || s[q].size() == 0))
        q--; // second 최빈값

      int j = *s[p].begin();
      if (i == j)
        j = *s[q].rbegin();

      // printf("%d vs %d\\n", p, q);
      // printf("match %d vs %d\\n", i, j);
      assert(!PA[j].empty());
      int k = PA[j].back();
      PA[j].pop_back();
      res[k] = i;
      if (AA[j])
        s[F[j]].erase(j);
      if (AA[i])
        s[F[i]].erase(i);
      AA[j]--;
      BB[i]--;
      F[j]--;
      F[i]--;
      if (AA[j])
        s[F[j]].insert(j);
      if (AA[i])
        s[F[i]].insert(i);

      // for(int i=1; i<=N; i++)
      // 	printf("%d ", res[i]);
      // printf("\\n");
    }
  }

  for (int i = 1; i <= N; i++)
    printf("%d ", res[i]);
  for (int i = 1; i <= N; i++)
    if (A[i] == res[i])
      assert(0);
  return 0;
}

Error: WA

Fixed submission:

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

#define INF 1234567890
#define ll long long

int N;
int A[200201], AA[200201], BB[200201], F[200201];
vector<int> PA[200201];
int res[200201];
set<int> s[200201];

int main() {
  scanf("%d", &N);
  for (int i = 1; i <= N; i++) {
    scanf("%d", &A[i]);
    AA[A[i]]++;
    F[A[i]]++;
    PA[A[i]].push_back(i);
  }
  for (int i = 1; i <= N; i++) {
    int t;
    scanf("%d", &t);
    BB[t]++;
    F[t]++;
  }
  // 가능성 판별
  for (int i = 1; i <= N; i++)
    if (F[i] > N)
      return !printf("No");
  printf("Yes\\n");

  for (int i = 1; i <= N; i++)
    s[F[i]].insert(i); // s[cnt] = col

  // 아무 순서로나 소거하자. 최빈값이랑 매칭시키자.
  int p = N, q = N;
  for (int i = 1; i <= N; i++) {
    while (BB[i] > 0) {
      while (s[p].empty())
        p--;
      q = min(q, p);
      while (q && s[p].size() == 1 && (p == q || s[q].size() == 0))
        q--; // second 최빈값

      int j = *s[p].begin();
      if (i == j)
        j = *s[q].rbegin();

      int k = PA[j].back();
      PA[j].pop_back();
      res[k] = i;
      AA[j]--;
      BB[i]--;
      s[F[j]].erase(j);
      s[F[i]].erase(i);
      F[j]--;
      F[i]--;
      s[F[j]].insert(j);
      s[F[i]].insert(i);

      // for(int i=1; i<=N; i++)
      // 	printf("%d ", res[i]);
      // printf("\\n");
    }
  }

  for (int i = 1; i <= N; i++)
    printf("%d ", res[i]);
  for (int i = 1; i <= N; i++)
    if (A[i] == res[i])
      assert(0);
  return 0;
}