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

#include <algorithm>
#include <iostream>
#include <stdio.h>
using namespace std;
#include <vector>
#define rep(i, n) for (int i = 0; i < (n); i++)
#define INF 1e9
#define llINF 1e18
#define MOD 1000000007
#define pb push_back
#define ll long long
#define ull unsigned long long
#define vint vector<int>
#define vll vector<ll>
#define base10_4 10000      // 1e4
#define base10_5 100000     // 1e5
#define base10_6 1000000    // 1e6
#define base10_7 10000000   // 1e7
#define base10_8 100000000  // 1e8
#define base10_9 1000000000 // 1e9
// #include <stack>
// #include <queue>

/*
#include <math.h>
int standerd = int(pow(10.0,9.0)) + 7;
*/
string ans_Yes = "Yes";
string ans_No = "No";
string ans_yes = "yes";
string ans_no = "no";
ll A[base10_6];
ll B[base10_6];
ll C;
ll N;
ll M;
ll K;

ll getPower(ll value, ll shisu, ll mod) {
  ll ans = 1;
  ll cnt = shisu;
  while (cnt > 0) {
    if (cnt % 2 == 1) {
      ans += MOD;
      ans = ans * value % mod;
    }
    value += MOD;
    value = value * value % mod;
    cnt = cnt / 2;
  }
  return ans;
}
long long koyaku_max(long long a, long long b) {
  long long r;
  r = a % b;
  while (r != 0) {
    a = b;
    b = r;
    r = a % b;
  }
  return b;
}

ll ans = 1;
#include <map>
int main() {

  cin >> N;
  rep(ni, N) {
    cin >> A[ni];
    cin >> B[ni];
  }

  map<string, ll> count_map[2];
  map<string, string> conv;
  int m_std = 0;
  int m_rev = 1;
  ll count_both_0 = 0;
  count_map[m_std]["0"] = 0;
  count_map[m_rev]["0"] = 0;
  conv["0"] = "0";

  rep(ni, N) {
    if (A[ni] == 0 && B[ni] == 0) {
      count_both_0++;
    } else {
      if (A[ni] == 0) {
        count_map[m_std]["0"]++;
      } else if (B[ni] == 0) {
        count_map[m_rev]["0"]++;
      } else {
        ll koyaku = koyaku_max(A[ni], B[ni]);
        A[ni] = A[ni] / koyaku;
        B[ni] = B[ni] / koyaku;
        string strA = to_string(abs(A[ni]));
        string strB = to_string(abs(B[ni]));
        string mark_std = "";
        string mark_rev = "";
        if (A[ni] * B[ni] < 0) {
          mark_std = "-";
        } else {
          mark_rev = "-";
        }

        string index1 = mark_std + strA + "/" + strB;
        string index2 = mark_rev + strB + "/" + strA;
        // cout << "-----------------" << endl;
        // cout << index1 << endl;
        // cout << index2 << endl;
        if (count_map[m_rev].count(index1) == 1) {
          count_map[m_rev][index1]++;
          // cout << "match rev" << endl;
        } else {
          if (count_map[m_std].count(index1) == 1) {
            // cout << "inc" << endl;
            count_map[m_std][index1]++;
          } else {
            // cout << "create" << endl;
            count_map[m_std][index1] = 1;
            count_map[m_rev][index2] = 0;
            conv[index1] = index2;
          }
        }
      }
    }
  }

  ll ans = 1;

  for (auto x : count_map[m_std]) {
    string key = x.first;
    ll value = x.second;
    ll tmp = 1;
    tmp += getPower(2, value, MOD) - 1;

    key = conv[key];
    value = count_map[m_rev][key];
    tmp += getPower(2, value, MOD) - 1;

    ans += MOD;
    ans = ans * tmp % MOD;
    // cout << ans << endl;
  }
  // cout << "--------" << endl;
  // cout << "answer is " << endl;
  ans = ans + count_both_0;
  ans = ans - 1 + MOD;
  ans = ans % MOD;
  cout << ans << endl;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <iostream>
#include <stdio.h>
using namespace std;
#include <vector>
#define rep(i, n) for (int i = 0; i < (n); i++)
#define INF 1e9
#define llINF 1e18
#define MOD 1000000007
#define pb push_back
#define ll long long
#define ull unsigned long long
#define vint vector<int>
#define vll vector<ll>

// #include <stack>
// #include <queue>

/*
#include <math.h>
int standerd = int(pow(10.0,9.0)) + 7;
*/
string ans_Yes = "Yes";
string ans_No = "No";
string ans_yes = "yes";
string ans_no = "no";
ll A[1000000];
ll B[1000000];
ll C;
ll N;
ll M;
ll K;

vector<int> root_size1; // parent[i]:iの親の番号　(例) parent[3] = 2 : 3の親が2
vector<int> root_size2; // parent[i]:iの親の番号　(例) parent[3] = 2 : 3の親が2
class UnionFind {
public:
  vector<int> parent; // parent[i]:iの親の番号　(例) parent[3] = 2 : 3の親が2
  UnionFind(int N) { // 最初は全てが根であるとして初期化
    for (int node_i = 0; node_i < N; node_i++) {
      int parent_i = node_i;
      parent.push_back(parent_i);
      root_size1.push_back(1);
      root_size2.push_back(0);
    }
  }
  bool
  isRoot(int x) { // データxが属する木の根を再帰で得る：root(x) = {xの木の根}
    if (parent[x] == x)
      return true;
    return false;
  }
  int getRoot(
      int x) { // データxが属する木の根を再帰で得る：root(x) = {xの木の根}
    if (parent[x] == x)
      return x;
    return parent[x] = getRoot(parent[x]);
  }
  void unite(int x, int y) { // xとyの木を併合
    int rx = getRoot(x);     // xの根をrx
    int ry = getRoot(y);     // yの根をry
    if (rx == ry)
      return; // xとyの根が同じ(=同じ木にある)時はそのまま
    parent[rx] =
        ry; // xとyの根が同じでない(=同じ木にない)時：xの根rxをyの根ryにつける
    root_size1[ry] = root_size2[rx] + root_size1[ry];
    root_size2[ry] = root_size1[rx] + root_size2[ry];
    root_size1[rx] = root_size2[rx] + root_size1[ry];
    root_size2[rx] = root_size1[rx] + root_size2[ry];
  }
  bool isSameRoot(int x,
                  int y) { // 2つのデータx, yが属する木が同じならtrueを返す
    int rx = getRoot(x);
    int ry = getRoot(y);
    return rx == ry;
  }
};

ll getPower(ll value, ll shisu, ll mod) {
  ll ans = 1;
  ll cnt = shisu;
  while (cnt > 0) {
    if (cnt % 2 == 1) {
      ans = ans * value % mod;
    }
    value = value * value % mod;
    cnt = cnt / 2;
  }
  return ans;
}

ll ans = 1;
int main() {

  cin >> N;
  rep(ni, N) {
    cin >> A[ni];
    cin >> B[ni];
  }
  UnionFind uf(N);

  for (int ni = 0; ni <= N - 1 - 1; ni++) {
    for (int mi = ni + 1; mi <= N - 1; mi++) {
      if (A[ni] * A[mi] + B[ni] * B[mi] == 0) {
        uf.unite(ni, mi);
      }
    }
  }

  rep(ni, N) {

    if (uf.isRoot(ni)) {
      ll base = ans;
      ans = ans + base * (getPower(2, root_size1[ni], MOD) - 1) % MOD;
      if (root_size2[ni] > 0)
        ans = ans + base * (getPower(2, root_size2[ni], MOD) - 1) % MOD;
      ans = ans % MOD;
    }
    // cout << ans << endl;
  }
  cout << ans - 1 << endl;
}