Problem p03968 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;
#define N 400 + 5
#define K 5
#define base 1000
#define int long long
#define rep(i, l, r) for (int i = l; i <= r; ++i)
int n, ans, C[N][K];
map<int, int> M;
int read() {
  char c;
  int x = 0, f = 1;
  c = getchar();
  while (c > '9' || c < '0') {
    if (c == '-')
      f = -1;
    c = getchar();
  }
  while (c >= '0' && c <= '9')
    x = x * 10 + c - '0', c = getchar();
  return x * f;
}
int Hash(int a, int b, int c, int d) {
  int ans = 0;
  ans = ans * base + a, ans = ans * base + b, ans = ans * base + c,
  ans = ans * base + d;
  return ans;
}
void update(int val, int x) {
  int a, b, c, d;
  d = val % base, val /= base;
  c = val % base, val /= base;
  b = val % base, val /= base;
  a = val % base, val /= base;
  M[Hash(a, b, c, d)] += x;
  M[Hash(b, c, d, a)] += x;
  M[Hash(c, d, a, b)] += x;
  M[Hash(d, a, b, c)] += x;
}
signed main() {
  n = read();
  rep(i, 1, n) {
    C[i][0] = read(), C[i][1] = read(), C[i][2] = read(), C[i][3] = read();
    update(Hash(C[i][0], C[i][1], C[i][2], C[i][3]), 1);
  }
  rep(i, 1, n) {
    update(Hash(C[i][0], C[i][1], C[i][2], C[i][3]), -1);
    rep(j, i + 1, n) {
      update(Hash(C[j][0], C[j][1], C[j][2], C[j][3]), -1);
      rep(k, 0, 3) {
        int AA = Hash(C[i][0], C[i][3], C[j][k], C[j][(3 + k) % 4]);
        int BB = Hash(C[i][3], C[i][2], C[j][(1 + k) % 4], C[j][k]);
        int CC = Hash(C[i][2], C[i][1], C[j][(2 + k) % 4], C[j][(1 + k) % 4]);
        int DD = Hash(C[i][1], C[i][0], C[j][(3 + k) % 4], C[j][(2 + k) % 4]);
        int a, b, c, d;
        a = M[AA], update(AA, -1);
        b = M[BB], update(BB, -1);
        c = M[CC], update(CC, -1);
        d = M[DD], update(DD, -1);
        if (a > 0 && b > 0 && c > 0 && d > 0)
          ans += a * b * c * d;
        update(AA, 1), update(BB, 1), update(CC, 1), update(DD, 1);
      }
      update(Hash(C[j][0], C[j][1], C[j][2], C[j][3]), 1);
    }
    update(Hash(C[i][0], C[i][1], C[i][2], C[i][3]), 1);
  }
  printf("%lld", ans / 3);
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
#define N 400 + 5
#define K 5
#define base 1000
#define int long long
#define rep(i, l, r) for (int i = l; i <= r; ++i)
int n, ans, C[N][K];
unordered_map<int, int> M;
int read() {
  char c;
  int x = 0, f = 1;
  c = getchar();
  while (c > '9' || c < '0') {
    if (c == '-')
      f = -1;
    c = getchar();
  }
  while (c >= '0' && c <= '9')
    x = x * 10 + c - '0', c = getchar();
  return x * f;
}
int Hash(int a, int b, int c, int d) {
  int ans = 0;
  ans = ans * base + a, ans = ans * base + b, ans = ans * base + c,
  ans = ans * base + d;
  return ans;
}
void update(int val, int x) {
  int a, b, c, d;
  d = val % base, val /= base;
  c = val % base, val /= base;
  b = val % base, val /= base;
  a = val % base, val /= base;
  M[Hash(a, b, c, d)] += x;
  M[Hash(b, c, d, a)] += x;
  M[Hash(c, d, a, b)] += x;
  M[Hash(d, a, b, c)] += x;
}
signed main() {
  n = read();
  rep(i, 1, n) {
    C[i][0] = read(), C[i][1] = read(), C[i][2] = read(), C[i][3] = read();
    update(Hash(C[i][0], C[i][1], C[i][2], C[i][3]), 1);
  }
  rep(i, 1, n) {
    update(Hash(C[i][0], C[i][1], C[i][2], C[i][3]), -1);
    rep(j, i + 1, n) {
      update(Hash(C[j][0], C[j][1], C[j][2], C[j][3]), -1);
      rep(k, 0, 3) {
        int AA = Hash(C[i][0], C[i][3], C[j][k], C[j][(3 + k) % 4]);
        int BB = Hash(C[i][3], C[i][2], C[j][(1 + k) % 4], C[j][k]);
        int CC = Hash(C[i][2], C[i][1], C[j][(2 + k) % 4], C[j][(1 + k) % 4]);
        int DD = Hash(C[i][1], C[i][0], C[j][(3 + k) % 4], C[j][(2 + k) % 4]);
        int a, b, c, d;
        a = M[AA], update(AA, -1);
        b = M[BB], update(BB, -1);
        c = M[CC], update(CC, -1);
        d = M[DD], update(DD, -1);
        if (a > 0 && b > 0 && c > 0 && d > 0)
          ans += a * b * c * d;
        update(AA, 1), update(BB, 1), update(CC, 1), update(DD, 1);
      }
      update(Hash(C[j][0], C[j][1], C[j][2], C[j][3]), 1);
    }
    update(Hash(C[i][0], C[i][1], C[i][2], C[i][3]), 1);
  }
  printf("%lld", ans / 3);
  return 0;
}