Problem p03968 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
int c[444][4], n;
int num[4][444];
void fd(int *num, int A, int B, int C, int D, int from, int no) {
  memset(num, 0, sizeof(int) * n);
  for (int i = from + 1; i < n; i++)
    if (i != no) {
      int E = c[i][0], F = c[i][1], G = c[i][2], H = c[i][3];
      num[i] = 0;
      if (A == E && B == F && C == G && D == H)
        num[i]++;
      if (B == E && C == F && D == G && A == H)
        num[i]++;
      if (C == E && D == F && A == G && B == H)
        num[i]++;
      if (D == E && A == F && B == G && C == H)
        num[i]++;
    }
}
long long int add(long long int x, long long int y) { return x + y; }
long long int sub(long long int x, long long int y) { return x - y; }
long long int mul(long long int x, long long int y) { return x * y; }
int calc(int id1, int from) {
  int res = 0;
  for (int i = from + 1; i < n; i++)
    res += num[id1][i];
  return res;
}
int calc(int id1, int id2, int from) {
  int res = 0;
  for (int i = from + 1; i < n; i++)
    res += num[id1][i] * num[id2][i];
  return res;
}
int calc(int id1, int id2, int id3, int from) {
  int res = 0;
  for (int i = from + 1; i < n; i++)
    res += num[id1][i] * num[id2][i] * num[id3][i];
  return res;
}
int calc(int id1, int id2, int id3, int id4, int from) {
  int res = 0;
  for (int i = from + 1; i < n; i++)
    res += num[id1][i] * num[id2][i] * num[id3][i] * num[id4][i];
  return res;
}
int main() {

  scanf("%d", &n);
  for (int i = 0; i < n; i++)
    for (int j = 0; j < 4; j++)
      scanf("%d", &c[i][j]);

  long long int res = 0;
  for (int i = 0; i < n; i++)
    for (int j = i + 1; j < n; j++)
      for (int k = 0; k < 4; k++) {
        int A = c[i][0];
        int B = c[i][1];
        int C = c[i][2];
        int D = c[i][3];
        int E = c[j][k % 4];
        int F = c[j][(k + 1) % 4];
        int G = c[j][(k + 2) % 4];
        int H = c[j][(k + 3) % 4];
        fd(num[0], B, E, H, C, i, j);
        fd(num[1], A, D, G, F, i, j);
        fd(num[2], F, E, B, A, i, j);
        fd(num[3], H, G, D, C, i, j);

        long long int A0 = calc(0, i);
        long long int A1 = calc(1, i);
        long long int A2 = calc(2, i);
        long long int A3 = calc(3, i);
        long long int A01 = calc(0, 1, i);
        long long int A02 = calc(0, 2, i);
        long long int A03 = calc(0, 3, i);
        long long int A12 = calc(1, 2, i);
        long long int A13 = calc(1, 3, i);
        long long int A23 = calc(2, 3, i);
        long long int A012 = calc(0, 1, 2, i);
        long long int A013 = calc(0, 1, 3, i);
        long long int A023 = calc(0, 2, 3, i);
        long long int A123 = calc(1, 2, 3, i);
        long long int A0123 = calc(0, 1, 2, 3, i);

        res = add(res, mul(mul(A0, A1), mul(A2, A3)));
        res = sub(res, mul(mul(A2, A3), A01));
        res = sub(res, mul(mul(A1, A3), A02));
        res = sub(res, mul(mul(A1, A2), A03));
        res = sub(res, mul(mul(A0, A3), A12));
        res = sub(res, mul(mul(A0, A2), A13));
        res = sub(res, mul(mul(A0, A1), A23));
        res = add(res, mul(A01, A23));
        res = add(res, mul(A02, A13));
        res = add(res, mul(A03, A12));
        res = add(res, mul(mul(A0, A123), 2));
        res = add(res, mul(mul(A1, A023), 2));
        res = add(res, mul(mul(A2, A013), 2));
        res = add(res, mul(mul(A3, A012), 2));
        res = sub(res, mul(A0123, 6));
      }
  cout << res << endl;
  return 0;
}

Fixed submission:
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
int c[444][4], n;
int num[4][444];
void fd(int *num, int A, int B, int C, int D, int from, int no) {
  long long int W = ((((((long long int)A << 10) + B) << 10) + C) << 10) + D;
  for (int i = from + 1; i < n; i++) {
    num[i] = 0;
    if (i == no)
      continue;
    int E = c[i][0], F = c[i][1], G = c[i][2], H = c[i][3];
    long long int hash =
        ((((((long long int)E << 10) + F) << 10) + G) << 10) + H;

    if (hash == W)
      num[i]++;
    hash = ((hash & ((1 << 30) - 1)) << 10) + E;
    if (hash == W)
      num[i]++;
    hash = ((hash & ((1 << 30) - 1)) << 10) + F;
    if (hash == W)
      num[i]++;
    hash = ((hash & ((1 << 30) - 1)) << 10) + G;
    if (hash == W)
      num[i]++;
  }
}
long long int add(long long int x, long long int y) { return x + y; }
long long int sub(long long int x, long long int y) { return x - y; }
long long int mul(long long int x, long long int y) { return x * y; }
int calc(int id1, int from) {
  int res = 0;
  for (int i = from + 1; i < n; i++)
    res += num[id1][i];
  return res;
}
int calc(int id1, int id2, int from) {
  int res = 0;
  for (int i = from + 1; i < n; i++)
    res += num[id1][i] * num[id2][i];
  return res;
}
int calc(int id1, int id2, int id3, int from) {
  int res = 0;
  for (int i = from + 1; i < n; i++)
    res += num[id1][i] * num[id2][i] * num[id3][i];
  return res;
}
int calc(int id1, int id2, int id3, int id4, int from) {
  int res = 0;
  for (int i = from + 1; i < n; i++)
    res += num[id1][i] * num[id2][i] * num[id3][i] * num[id4][i];
  return res;
}
int main() {

  scanf("%d", &n);
  for (int i = 0; i < n; i++)
    for (int j = 0; j < 4; j++)
      scanf("%d", &c[i][j]);

  long long int res = 0;
  for (int i = 0; i < n; i++)
    for (int j = i + 1; j < n; j++)
      for (int k = 0; k < 4; k++) {
        int A = c[i][0];
        int B = c[i][1];
        int C = c[i][2];
        int D = c[i][3];
        int E = c[j][k % 4];
        int F = c[j][(k + 1) % 4];
        int G = c[j][(k + 2) % 4];
        int H = c[j][(k + 3) % 4];
        fd(num[0], B, E, H, C, i, j);
        fd(num[1], A, D, G, F, i, j);
        fd(num[2], F, E, B, A, i, j);
        fd(num[3], H, G, D, C, i, j);

        long long int A0 = calc(0, i);
        long long int A1 = calc(1, i);
        long long int A2 = calc(2, i);
        long long int A3 = calc(3, i);
        long long int A01 = calc(0, 1, i);
        long long int A02 = calc(0, 2, i);
        long long int A03 = calc(0, 3, i);
        long long int A12 = calc(1, 2, i);
        long long int A13 = calc(1, 3, i);
        long long int A23 = calc(2, 3, i);
        long long int A012 = calc(0, 1, 2, i);
        long long int A013 = calc(0, 1, 3, i);
        long long int A023 = calc(0, 2, 3, i);
        long long int A123 = calc(1, 2, 3, i);
        long long int A0123 = calc(0, 1, 2, 3, i);

        res = add(res, mul(mul(A0, A1), mul(A2, A3)));
        res = sub(res, mul(mul(A2, A3), A01));
        res = sub(res, mul(mul(A1, A3), A02));
        res = sub(res, mul(mul(A1, A2), A03));
        res = sub(res, mul(mul(A0, A3), A12));
        res = sub(res, mul(mul(A0, A2), A13));
        res = sub(res, mul(mul(A0, A1), A23));
        res = add(res, mul(A01, A23));
        res = add(res, mul(A02, A13));
        res = add(res, mul(A03, A12));
        res = add(res, mul(mul(A0, A123), 2));
        res = add(res, mul(mul(A1, A023), 2));
        res = add(res, mul(mul(A2, A013), 2));
        res = add(res, mul(mul(A3, A012), 2));
        res = sub(res, mul(A0123, 6));
      }
  cout << res << endl;
  return 0;
}