Problem p02588 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <algorithm>
#include <climits>
#include <cmath>
#include <iostream>
#include <map>
#include <set>
#include <vector>

using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;

#define MOD 1000000007LL
#define DMAX 1000000000ULL
#define DHLF 100000LL

int n2min, n2max, n5min, n5max;

class dfloat {
public:
  ull dint;
  int n2;
  int n5;
  dfloat() {
    dint = 0;
    n2 = 0;
    n5 = 0;
  }
  dfloat(ull n) {
    dint = n;
    n2 = 0;
    n5 = 0;
  }
  dfloat(const dfloat &df) {
    dint = df.dint;
    n2 = df.n2;
    n5 = df.n5;
  }
  dfloat(string s) {
    bool si = true;
    dint = 0;
    n2 = 0;
    n5 = 0;
    for (int i = 0; i < (int)s.size(); i++) {
      if (s[i] == '.') {
        si = false;
        continue;
      }
      dint *= 10;
      dint += s[i] - '0';
      if (!si) {
        n2--;
        n5--;
      }
    }
    while (dint % 2 == 0) {
      dint /= 2;
      n2++;
    }
    while (dint % 5 == 0) {
      dint /= 5;
      n5++;
    }
  }
  dfloat operator=(const dfloat &);
  //  const dfloat operator + (const dfloat &) const;
  const dfloat operator*(const dfloat &) const;
};

dfloat dfloat::operator=(const dfloat &df) {
  this->dint = df.dint;
  this->n2 = df.n2;
  this->n5 = df.n5;
  return *this;
}
/*
const dfloat dfloat::operator + (const dfloat &df) const {
}
  */

const dfloat dfloat::operator*(const dfloat &df) const {
  dfloat dr;

  dr.dint = this->dint * df.dint;
  dr.n2 = this->n2 + df.n2;
  dr.n5 = this->n5 + df.n5;

  return dr;
}

int n;
vector<dfloat> a;
vector<vector<int>> mat;

#define mmat(x, y) mat[(x)-n2min][(y)-n5min]

int is_int(dfloat d1, dfloat d2) {

  // printf("%llu*2^%d*5^%d * %llu*2^%d*5^%d = ", d1.dint, d1.n2, d1.n5,
  // d2.dint, d2.n2, d2.n5);

  dfloat d3 = d1 * d2;
  // printf("%llu*2^%d*5^%d\\n", d3.dint, d3.n2, d3.n5);
  if (d3.n2 >= 0 && d3.n5 >= 0)
    return 1;
  return 0;
}
int main() {
  ll ans = 0;
  string s;

  n2min = n5min = 100;
  n2max = n5max = -100;
  cin >> n;

  a.resize(n);
  for (int i = 0; i < n; i++) {
    cin >> s;
    a[i] = dfloat(s);
    if (a[i].n2 < n2min)
      n2min = a[i].n2;
    if (a[i].n5 < n5min)
      n5min = a[i].n5;
    if (a[i].n2 > n2max)
      n2max = a[i].n2;
    if (a[i].n5 > n5max)
      n5max = a[i].n5;
    // cout << s; printf(" = %llu*2^%d*5^%d\\n", a[i].dint, a[i].n2, a[i].n5);
  }

  // printf("n2 [%d - %d]\\n", n2min, n2max);
  // printf("n5 [%d - %d]\\n", n5min, n5max);

  mat.resize(n2max - n2min + 1);
  for (int i = n2min; i <= n2max; i++) {
    mat[i - n2min].resize(n5max - n5min + 1);
  }
  for (int i = 0; i < n; i++) {
    mmat(a[i].n2, a[i].n5)++;
  }

  /*
  printf("    ");
  for (int x5=n5min; x5<=n5max; x5++) printf("%3d ", x5);
  printf("\\n");
  for (int x5=n5min; x5<=n5max+1; x5++) printf("----");
  printf("\\n");
  for (int x2=n2min; x2<=n2max; x2++) {
    printf("%3d|", x2);
    for (int x5=n5min; x5<=n5max; x5++) {
      printf("%3d ", mmat(x2, x5));
    }
    printf("\\n");
  }
    */

  for (int i = 0; i < n; i++) {
    // printf("[%d %d]\\n", a[i].n2, a[i].n5);
    for (int x2 = max(-a[i].n2, n2min); x2 <= n2max; x2++) {
      for (int x5 = max(-a[i].n5, n5min); x5 <= n5max; x5++) {
        // printf("mmat(%d, %d) = %d\\n", x2, x5, mmat(x2, x5));
        ans += mmat(x2, x5);
        if (x2 == a[i].n2 && x5 == a[i].n5)
          ans--;
      }
    }
  }

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

/*
  a.b * c.d =
  a*c + a*d/M + b*c/M
  */


Error: TLE

Fixed submission:

#include <algorithm>
#include <climits>
#include <cmath>
#include <iostream>
#include <map>
#include <set>
#include <vector>

using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;

#define MOD 1000000007LL
#define DMAX 1000000000ULL
#define DHLF 100000LL

class dfloat {
public:
  ull dint;
  int n2;
  int n5;
  dfloat() {
    dint = 0;
    n2 = 0;
    n5 = 0;
  }
  dfloat(ull n) {
    dint = n;
    n2 = 0;
    n5 = 0;
  }
  dfloat(const dfloat &df) {
    dint = df.dint;
    n2 = df.n2;
    n5 = df.n5;
  }
  dfloat(string s) {
    bool si = true;
    dint = 0;
    n2 = 0;
    n5 = 0;
    for (int i = 0; i < (int)s.size(); i++) {
      if (s[i] == '.') {
        si = false;
        continue;
      }
      dint *= 10;
      dint += s[i] - '0';
      if (!si) {
        n2--;
        n5--;
      }
    }
    while (dint % 2 == 0) {
      dint /= 2;
      n2++;
    }
    while (dint % 5 == 0) {
      dint /= 5;
      n5++;
    }
  }
  dfloat operator=(const dfloat &);
  //  const dfloat operator + (const dfloat &) const;
  const dfloat operator*(const dfloat &) const;
};

dfloat dfloat::operator=(const dfloat &df) {
  this->dint = df.dint;
  this->n2 = df.n2;
  this->n5 = df.n5;
  return *this;
}
/*
const dfloat dfloat::operator + (const dfloat &df) const {
}
  */

const dfloat dfloat::operator*(const dfloat &df) const {
  dfloat dr;

  dr.dint = this->dint * df.dint;
  dr.n2 = this->n2 + df.n2;
  dr.n5 = this->n5 + df.n5;

  return dr;
}

int n;
vector<string> a;

int is_int(string i1, string i2) {
  dfloat d1(i1);
  dfloat d2(i2);

  // printf("%llu*2^%d*5^%d * %llu*2^%d*5^%d = ", d1.dint, d1.n2, d1.n5,
  // d2.dint, d2.n2, d2.n5);

  dfloat d3 = d1 * d2;
  // printf("%llu*2^%d*5^%d\\n", d3.dint, d3.n2, d3.n5);
  if (d3.n2 >= 0 && d3.n5 >= 0)
    return 1;
  return 0;
}
int main() {
  ll ans = 0;

  cin >> n;

  a.resize(n);
  for (int i = 0; i < n; i++) {
    cin >> a[i];
  }

  for (int i = 0; i < n - 1; i++) {
    for (int j = i + 1; j < n; j++) {
      ans += is_int(a[i], a[j]);
    }
  }

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

/*
  a.b * c.d =
  a*c + a*d/M + b*c/M
  */