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

#include <bits/stdc++.h>
using namespace std;
using LL = int64_t;
using ULL = int64_t;
using P = pair<LL, LL>;
#define rep(i, n) for (LL i = 0; i < (n); ++i)
#define all(v) (v).begin(), (v).end()
#define DEBUG

// normalized vector elements, # of colinear, # of orthogonal.
typedef map<pair<LL, LL>, pair<LL, LL>> table;

// Return 2^n mod 1000000007LL.
LL pow2(const LL n) {
  assert(n >= 0);
  LL prod = 1LL;
  rep(i, n) {
    prod *= 2LL;
    prod %= 1000000007LL;
  }
  return prod;
}

LL count(table &t) {
  LL prod = 1LL;
  for (const auto &e : t) {
    const auto n_colinear = e.second.first;
    const auto n_scalar = e.second.second;
    // LL this_prod = pow2(n_scalar) - 1LL;
    LL this_prod = pow2(n_scalar) + 1000000006LL;
    this_prod %= 1000000007LL;
    // this_prod += pow2(n_colinear) - 1LL;
    this_prod += pow2(n_colinear) + 1000000006LL;
    this_prod %= 1000000007LL;
    this_prod += 1LL; // No vectors are selected.
    this_prod %= 1000000007LL;
    prod *= this_prod;
    prod %= 1000000007LL;
  }
  prod = (prod + 1000000006LL) % 1000000007LL; // decrement.
  return prod;
}

LL gcd(LL n, LL m) {
  // Assume n <= m.
  while (m % n != 0LL) {
    LL p = m % n;
    m = n;
    n = p;
  }
  return n;
}

LL gcd_w_swap(LL n, LL m) {
  // Assume 0 < n, 0 < m.
  if (n > m) {
    return gcd(m, n);
  } else {
    return gcd(n, m);
  }
}

int main() {
  table t;
  LL n;
  cin >> n;

  if (n == 1) {
    cout << 1 << endl;
    return 0;
  }

  LL count_zero_zero = 0LL;

  rep(i, n) {
    LL aa, bb;
    cin >> aa >> bb;

    // Normalize
    if (aa == 0LL && bb == 0LL) {
      count_zero_zero++;
      continue;
    }
    if (bb == 0LL) {
      aa = 1LL; // (1, 0)
    } else if (aa == 0LL) {
      bb = 1LL; // (0, 1)
    } else {
      // A /= 0, B /= 0.
      if (bb < 0) {
        aa *= -1;
        bb *= -1;
      }
      // A /= 0, B > 0.
      LL d = gcd_w_swap(abs(aa), bb);
      aa /= d;
      bb /= d;
    }
    //    cout << aa << " : " << bb << endl;

    // Determine canonical form
    auto cpair = make_pair(aa, bb);
    if (bb == 0) {
      cpair = make_pair(0LL, 1LL);
    } else if (aa < 0) {
      cpair = make_pair(bb, -aa);
    }

    // Update table
    try {
      auto pair_of_numbers = t.at(cpair); // This may throws an exception.
      if (aa < 0 || (aa == 1 && bb == 0)) {
        pair_of_numbers.second++;
      } else {
        pair_of_numbers.first++;
      }
      t[cpair] = pair_of_numbers;
    } catch (...) {
      // No such pair.
      auto pair_of_numbers = make_pair(1LL, 0LL);
      if (aa < 0 || (aa == 1 && bb == 0)) {
        pair_of_numbers = make_pair(0LL, 1LL);
      }
      t.insert(make_pair(cpair, pair_of_numbers));
    }
  }

  // // Normalized input 1
  // t.insert(make_pair(make_pair(1LL, 2LL), make_pair(1LL, 1LL)));
  // t.insert(make_pair(make_pair(-1LL, 1LL), make_pair(1LL, 0LL)));

  // Normalized input 2
  // t.insert(make_pair(make_pair(3LL, 2LL), make_pair(2LL, 1LL)));
  // t.insert(make_pair(make_pair(-1LL, 1LL), make_pair(1LL, 1LL)));
  // t.insert(make_pair(make_pair(-2LL, 1LL), make_pair(1LL, 0LL)));
  // t.insert(make_pair(make_pair(1LL, 3LL), make_pair(1LL, 0LL)));
  // t.insert(make_pair(make_pair(8LL, 1LL), make_pair(1LL, 0LL)));
  // t.insert(make_pair(make_pair(4LL, 1LL), make_pair(1LL, 0LL)));
  // t.insert(make_pair(make_pair(2LL, 1LL), make_pair(1LL, 0LL)));

  //  for (const auto &e: t) {
  //    cout << e.first.first << " " << e.first.second << " : "
  //         << e.second.first << " " << e.second.second << endl;
  //  }

  cout << (count(t) + count_zero_zero) % 1000000007LL << endl;

#ifdef DEBUG
// cout << 123 << endl;
#endif
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
using LL = int64_t;
using ULL = int64_t;
using P = pair<LL, LL>;
#define rep(i, n) for (LL i = 0; i < (n); ++i)
#define all(v) (v).begin(), (v).end()
#define DEBUG

vector<LL> s;
vector<LL> a;
vector<LL> b;

LL dfs(const LL &n, const LL depth) {
  if (depth == n) {
    return 1LL;
  }
  LL sum = 0;
  sum += dfs(n, depth + 1);
  bool new_fish = true;
  for (const auto &existed : s) {
    const auto val = a[existed] * a[depth] + b[existed] * b[depth];
    if (val == 0) {
      new_fish = false;
      break;
    }
  }
  if (new_fish) {
    // Additional fish.
    s.push_back(depth);
    sum += dfs(n, depth + 1);
    s.pop_back();
  }
  return sum % 1000000007LL;
}

int main() {
  LL n;
  cin >> n;

  rep(i, n) {
    LL aa, bb;
    cin >> aa >> bb;
    a.push_back(aa);
    b.push_back(bb);
  }
  auto sum = dfs(n, 0);

  cout << sum - 1 << endl;

#ifdef DEBUG
// cout << 123 << endl;
#endif
}