Problem p03912 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <bitset>
#include <cassert>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits.h>
#include <map>
#include <math.h>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;

int N, M;
vector<int> X;
vector<int> mod; // mod[i] := あまりiになるXの要素の個数
typedef pair<int, int> pii;
vector<vector<pii>> mods; // 何個、何があるのか

int main() {
  cin >> N >> M;
  X.resize(N);
  mod.resize(M, 0);
  for (int n = 0; n < N; n++) {
    cin >> X[n];
    mod[X[n] % M]++;
  }
  sort(X.begin(), X.end());
  mods.resize(M);
  pii cur = pii(1, X[0]);
  for (int n = 1; n < N; n++) {
    if (X[n] == X[n - 1])
      cur.first++;
    else {
      mods[X[n - 1] % M].push_back(cur);
      cur = pii(1, X[n]);
    }
  }
  mods[X[N - 1] % M].push_back(cur);
  for (int m = 0; m < M; m++) {
    sort(mods[m].begin(), mods[m].end());
  }
  long long ans = 0;
  for (int i = 0; i < M; i++) {
    int j = (M - i) % M;
    if (i > j)
      continue;
    // 自分自身とマッチング
    if (i == j)
      ans += mod[i] / 2;
    else {
      ans += min(mod[i], mod[j]);
      if (mod[i] > mod[j]) {
        int del = mod[j]; // 自分のグループとマッチングさせたい個数
        for (int l = 0; l < mods[i].size() && del > 0; l++) {
          if (mods[i][l].first % 2 == 1) {
            mods[i][l].first--;
            del--;
          }
        }
        if (del == 0) {
          int tempans = 0;
          for (int l = 0; l < mods[i].size(); l++) {
            tempans += mods[i][l].first / 2;
          }
          ans += tempans;
        } else {
          if (del % 2 == 1)
            del++;
          int tempans = 0;
          for (int l = 0; l < mods[i].size(); l++) {
            tempans += mods[i][l].first / 2;
          }
          ans += tempans - del / 2;
        }
      } else if (mod[i] < mod[j]) {
        int del = mod[i]; // 自分のグループとマッチングさせたい個数
        for (int l = 0; l < mods[i].size() && del > 0; l++) {
          if (mods[j][l].first % 2 == 1) {
            mods[j][l].first--;
            del--;
          }
        }
        if (del == 0) {
          int tempans = 0;
          for (int l = 0; l < mods[j].size(); l++) {
            tempans += mods[j][l].first / 2;
          }
          ans += tempans;

        } else {
          if (del % 2 == 1)
            del++;
          int tempans = 0;
          for (int l = 0; l < mods[j].size(); l++) {
            tempans += mods[j][l].first / 2;
          }
          ans += tempans - del / 2;
        }
      }
    }
  }
  cout << ans << endl;
  return 0;
}

Fixed submission:
#include <algorithm>
#include <bitset>
#include <cassert>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits.h>
#include <map>
#include <math.h>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;

int N, M;
vector<int> X;
vector<int> mod; // mod[i] := あまりiになるXの要素の個数
typedef pair<int, int> pii;
vector<vector<pii>> mods; // 何個、何があるのか

int main() {
  cin >> N >> M;
  X.resize(N);
  mod.resize(M, 0);
  for (int n = 0; n < N; n++) {
    cin >> X[n];
    mod[X[n] % M]++;
  }
  sort(X.begin(), X.end());
  mods.resize(M);
  pii cur = pii(1, X[0]);
  for (int n = 1; n < N; n++) {
    if (X[n] == X[n - 1])
      cur.first++;
    else {
      mods[X[n - 1] % M].push_back(cur);
      cur = pii(1, X[n]);
    }
  }
  mods[X[N - 1] % M].push_back(cur);
  for (int m = 0; m < M; m++) {
    sort(mods[m].begin(), mods[m].end());
  }
  long long ans = 0;
  for (int i = 0; i < M; i++) {
    int j = (M - i) % M;
    if (i > j)
      continue;
    // 自分自身とマッチング
    if (i == j)
      ans += mod[i] / 2;
    else {
      ans += min(mod[i], mod[j]);
      if (mod[i] > mod[j]) {
        int del = mod[j]; // 自分のグループとマッチングさせたい個数
        for (int l = 0; l < mods[i].size() && del > 0; l++) {
          if (mods[i][l].first % 2 == 1) {
            mods[i][l].first--;
            del--;
          }
        }
        if (del == 0) {
          int tempans = 0;
          for (int l = 0; l < mods[i].size(); l++) {
            tempans += mods[i][l].first / 2;
          }
          ans += tempans;
        } else {
          if (del % 2 == 1)
            del++;
          int tempans = 0;
          for (int l = 0; l < mods[i].size(); l++) {
            tempans += mods[i][l].first / 2;
          }
          ans += tempans - del / 2;
        }
      } else if (mod[i] < mod[j]) {
        int del = mod[i]; // 自分のグループとマッチングさせたい個数
        for (int l = 0; l < mods[j].size() && del > 0; l++) {
          if (mods[j][l].first % 2 == 1) {
            mods[j][l].first--;
            del--;
          }
        }
        if (del == 0) {
          int tempans = 0;
          for (int l = 0; l < mods[j].size(); l++) {
            tempans += mods[j][l].first / 2;
          }
          ans += tempans;

        } else {
          if (del % 2 == 1)
            del++;
          int tempans = 0;
          for (int l = 0; l < mods[j].size(); l++) {
            tempans += mods[j][l].first / 2;
          }
          ans += tempans - del / 2;
        }
      }
    }
  }
  cout << ans << endl;
  return 0;
}