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

#define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
using ll = long long;
const ll MOD = 1000000007;
const long long INF = 1LL << 60;
const double pi = acos(-1.0);

template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}

pair<ll, ll> my_stoi(string S) {
  ll N = S.size();
  ll ret = 0;
  ll point;
  rep(i, N) {
    if (S.at(i) == '.') {
      point = i;
      continue;
    }
    ret *= 10;
    ret += S.at(i) - '0';
  }
  ll keta = 1;
  rep(i, N - point - 1) keta *= 10;

  return {ret, keta};
}

int main() {
  ll N;
  cin >> N;
  vector<string> A(N);
  rep(i, N) cin >> A.at(i);

  // 2と5で何回割れるか
  vector<pair<ll, ll>> vec(N);
  rep(i, N) {
    ll bunsi, bunbo;
    tie(bunsi, bunbo) = my_stoi(A.at(i));
    ll a = bunsi * (1000000000 / bunbo);
    ll c2 = 0, c5 = 0;
    while (a % 2 == 0) {
      a /= 2;
      c2++;
    }
    while (a % 5 == 0) {
      a /= 5;
      c5++;
    }

    vec.at(i) = {c2, c5};
  }

  // 二次元累積和
  vector<vector<ll>> svec(50, vector<ll>(50, 0));

  rep(i, N) {
    ll c2, c5;
    tie(c2, c5) = vec.at(i);
    svec.at(c2).at(c5)++;
  }
  rep(i, 50) {
    for (int j = 48; j >= 0; j--) {
      svec.at(i).at(j) += svec.at(i).at(j + 1);
    }
  }
  rep(i, 50) {
    for (int j = 48; j >= 0; j--) {
      svec.at(j).at(i) += svec.at(j + 1).at(i);
    }
  }

  // 解法部分
  ll ans = 0;
  rep(i, N) {
    ll c2, c5;
    tie(c2, c5) = vec.at(i);
    ans += svec.at(max((int)(18 - c2), 0)).at(max((int)(18 - c5), 0));
    if (c2 * 2 >= 18 && c5 * 2 >= 18)
      ans--;
  }

  cout << ans / 2 << endl;
  return 0;
}

Error: 0

Fixed submission:

#define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
using ll = long long;
const ll MOD = 1000000007;
const long long INF = 1LL << 60;
const double pi = acos(-1.0);

template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}

int main() {
  ll N;
  cin >> N;
  vector<pair<ll, ll>> A(N);

  // 既約分数の形にする
  rep(i, N) {
    string S;
    cin >> S;
    ll sz = S.size(), point = -1;
    rep(j, sz) {
      if (S.at(j) == '.')
        point = j;
    }

    if (point == -1) {
      A.at(i) = {stoi(S), 1};
      continue;
    }
    string Q = S.substr(0, point), D = S.substr(point + 1, sz - point - 1);
    ll bunbo = pow(10, sz - point - 1), bunsi = stoi(D);
    while ((bunsi % 2 == 0 && bunbo % 2 == 0) ||
           (bunsi % 5 == 0 && bunbo % 5 == 0)) {
      if (bunsi % 2 == 0 && bunbo % 2 == 0) {
        bunsi /= 2;
        bunbo /= 2;
      }
      if (bunsi % 5 == 0 && bunbo % 5 == 0) {
        bunsi /= 5;
        bunbo /= 5;
      }
    }
    A.at(i) = {(ll)stoi(Q) * bunbo + bunsi, bunbo};
  }

  ll ans = 0;

  // 整数同士の数え上げ
  ll sum = 0;
  rep(i, N) if (A.at(i).second == 1) sum++;
  ans += sum * (sum - 1) / 2;

  // cout<<ans<<endl;
  // 分母が10の倍数であるものと整数のペアの数え上げ
  vector<vector<ll>> table(10, vector<ll>(10, 0));
  rep(i, N) {
    if (A.at(i).second == 1) {
      ll a = A.at(i).first;
      ll b2 = 0, b5 = 0;
      while (a % 2 == 0) {
        a /= 2;
        b2++;
      }
      while (a % 5 == 0) {
        a /= 5;
        b5++;
      }

      table.at(b2).at(b5)++;
    }
  }
  rep(i, 10) {
    for (int j = 8; j >= 0; j--) {
      table.at(i).at(j) += table.at(i).at(j + 1);
    }
  }
  rep(i, 10) {
    for (int j = 8; j >= 0; j--) {
      table.at(j).at(i) += table.at(j + 1).at(j);
    }
  }

  rep(i, N) {
    ll a = A.at(i).second;
    if (a % 2 == 0 && a % 5 == 0) {
      ll b2 = 0, b5 = 0;
      while (a % 2 == 0) {
        a /= 2;
        b2++;
      }
      while (a % 5 == 0) {
        a /= 5;
        b5++;
      }
      ans += table.at(b2).at(b5);
    }
  }

  // cout<<ans<<endl;
  // 分母が2の累乗の奴と分母が5の累乗のやつの数え上げ
  table = vector<vector<ll>>(10, vector<ll>(10, 0));
  rep(i, N) {
    ll bunsi, bunbo;
    tie(bunsi, bunbo) = A.at(i);
    if (bunbo % 5 == 0 && bunbo % 2 != 0) {
      ll b2 = 0, b5 = 0;
      while (bunsi % 2 == 0) {
        bunsi /= 2;
        b2++;
      }
      while (bunbo % 5 == 0) {
        bunbo /= 5;
        b5++;
      }

      table.at(min((int)b2, 9)).at(b5)++;
    }
  }
  rep(i, 10) {
    rep(j, 9) { table.at(i).at(j + 1) += table.at(i).at(j); }
  }
  rep(i, 10) {
    for (int j = 8; j >= 0; j--) {
      table.at(j).at(i) += table.at(j + 1).at(j);
    }
  }

  rep(i, N) {
    ll bunsi, bunbo;
    tie(bunsi, bunbo) = A.at(i);
    if (bunbo % 2 == 0 && bunbo % 5 != 0) {
      ll b2 = 0, b5 = 0;
      while (bunbo % 2 == 0) {
        bunbo /= 2;
        b2++;
      }
      while (bunsi % 5 == 0) {
        bunsi /= 5;
        b5++;
      }
      ans += table.at(b2).at(min((int)b5, 9));
    }
  }

  // 分母が5の累乗のやつと整数のやつのペア
  vector<ll> vec(10, 0);
  rep(i, N) {
    if (A.at(i).second == 1) {
      ll b5 = 0;
      ll a = A.at(i).first;
      while (a % 5 == 0) {
        a /= 5;
        b5++;
      }
      vec.at(min(9, (int)b5))++;
    }
  }
  for (int i = 8; i >= 0; i--) {
    vec.at(i) += vec.at(i + 1);
  }

  rep(i, N) {
    ll bunsi, bunbo;
    tie(bunsi, bunbo) = A.at(i);
    if (bunbo % 5 == 0 && bunbo % 2 != 0) {
      ll b5 = 0;
      while (bunbo % 5 == 0) {
        bunbo /= 5;
        b5++;
      }

      ans += vec.at(b5);
    }
  }

  // 2の(ry
  vec = vector<ll>(10, 0);
  rep(i, N) {
    if (A.at(i).second == 1) {
      ll b2 = 0;
      ll a = A.at(i).first;
      while (a % 2 == 0) {
        a /= 2;
        b2++;
      }
      vec.at(min(9, (int)b2))++;
    }
  }
  for (int i = 8; i >= 0; i--) {
    vec.at(i) += vec.at(i + 1);
  }

  rep(i, N) {
    ll bunsi, bunbo;
    tie(bunsi, bunbo) = A.at(i);
    if (bunbo % 2 == 0 && bunbo % 5 != 0) {
      ll b2 = 0;
      while (bunbo % 2 == 0) {
        bunbo /= 2;
        b2++;
      }

      ans += vec.at(b2);
    }
  }

  cout << ans << endl;
  return 0;
}