Problem p03922 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cmath>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
#define _repargs(_1, _2, _3, name, ...) name
#define _rep(i, n) repi(i, 0, n)
#define repi(i, a, b) for (int i = (int)(a); i < (int)(b); ++i)
#define rep(...) _repargs(__VA_ARGS__, repi, _rep, )(__VA_ARGS__)
#define all(x) (x).begin(), (x).end()
#define mod 1000000007
#define inf 2000000007
#define mp make_pair
#define pb push_back
typedef long long ll;
using namespace std;
template <typename T> inline void output(T a, int p = 0) {
  if (p)
    cout << fixed << setprecision(p) << a << "\n";
  else
    cout << a << "\n";
}
// end of template

int main() {
  cin.tie(0);
  ios::sync_with_stdio(0);
  // source code

  int N, M;
  cin >> N >> M;
  vector<int> cnt(100);
  vector<int> A(M); // あまりがiの個数
  rep(i, N) {
    int a;
    cin >> a;
    cnt[a]++;
    A[a % M]++;
  }
  int ans = 0;
  ans += A[0] / 2;
  if (M % 2 == 0)
    ans += A[M / 2] / 2;

  vector<int> R(M); // 奇数個の個数
  vector<int> D(M);
  rep(i, cnt.size()) {
    if (cnt[i] % 2 == 1)
      R[i % M]++;
  }
  rep(i, 1, M) {
    if (i == M - i)
      continue;
    if (R[i] && R[M - i]) {
      int m = min(R[i], R[M - i]);
      ans += m;
      R[i] -= m;
      R[M - i] -= m;
      D[i] += m;
      D[M - i] += m;
      A[i] -= m;
      A[M - i] -= m;
    }
  }
  rep(i, cnt.size()) {
    if (cnt[i] % 2 == 1 && D[i % M] > 0) {
      cnt[i]--, D[i % M]--;
    }
  }
  vector<int> P(M);

  rep(i, cnt.size()) { P[i % M] += cnt[i] / 2; }

  rep(i, 1, M) {
    if (i == M - i)
      continue;
    int m = min(A[i], A[M - i]);
    A[i] -= m;
    A[M - i] -= m;
    ans += m;
  }

  rep(i, 1, M) {
    if (i != M - i)
      ans += min(P[i], A[i] / 2);
  }

  //    rep(i, cnt.size()){
  //        ans += cnt[i] / 2;
  //    }
  //
  //    rep(i, 1, M){
  //        if(R[i] > 0 && A[M - i] > 0){
  //            int m = min(R[i], A[M - i]);
  //            A[M - i] -= m;
  //            ans += m / 2;
  //        }
  //    }

  output(ans);

  return 0;
}

Fixed submission:
#include <algorithm>
#include <cmath>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
#define _repargs(_1, _2, _3, name, ...) name
#define _rep(i, n) repi(i, 0, n)
#define repi(i, a, b) for (int i = (int)(a); i < (int)(b); ++i)
#define rep(...) _repargs(__VA_ARGS__, repi, _rep, )(__VA_ARGS__)
#define all(x) (x).begin(), (x).end()
#define mod 1000000007
#define inf 2000000007
#define mp make_pair
#define pb push_back
typedef long long ll;
using namespace std;
template <typename T> inline void output(T a, int p = 0) {
  if (p)
    cout << fixed << setprecision(p) << a << "\n";
  else
    cout << a << "\n";
}
// end of template

int main() {
  cin.tie(0);
  ios::sync_with_stdio(0);
  // source code

  int N, M;
  cin >> N >> M;
  vector<int> cnt(100001);
  vector<int> A(M); // あまりがiの個数
  rep(i, N) {
    int a;
    cin >> a;
    cnt[a]++;
    A[a % M]++;
  }
  int ans = 0;
  ans += A[0] / 2;
  if (M % 2 == 0)
    ans += A[M / 2] / 2;

  vector<int> R(M); // 奇数個の個数
  vector<int> D(M);
  rep(i, cnt.size()) {
    if (cnt[i] % 2 == 1)
      R[i % M]++;
  }
  rep(i, 1, M) {
    if (i == M - i)
      continue;
    if (R[i] && R[M - i]) {
      int m = min(R[i], R[M - i]);
      ans += m;
      R[i] -= m;
      R[M - i] -= m;
      D[i] += m;
      D[M - i] += m;
      A[i] -= m;
      A[M - i] -= m;
    }
  }
  rep(i, cnt.size()) {
    if (cnt[i] % 2 == 1 && D[i % M] > 0) {
      cnt[i]--, D[i % M]--;
    }
  }
  vector<int> P(M);

  rep(i, cnt.size()) { P[i % M] += cnt[i] / 2; }

  rep(i, 1, M) {
    if (i == M - i)
      continue;
    int m = min(A[i], A[M - i]);
    A[i] -= m;
    A[M - i] -= m;
    ans += m;
  }

  rep(i, 1, M) {
    if (i != M - i)
      ans += min(P[i], A[i] / 2);
  }

  //    rep(i, cnt.size()){
  //        ans += cnt[i] / 2;
  //    }
  //
  //    rep(i, 1, M){
  //        if(R[i] > 0 && A[M - i] > 0){
  //            int m = min(R[i], A[M - i]);
  //            A[M - i] -= m;
  //            ans += m / 2;
  //        }
  //    }

  output(ans);

  return 0;
}