Problem p02414 (C++)

Buggy submission (status: Memory Limit Exceeded):
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <vector>

using namespace std;

using intp = long long int *;
using intpp = long long int **;

intpp subtract(intpp a, intpp b, int sz);
intpp add(intpp a, intpp b, int sz);
intpp combine(intpp a, intpp b, intpp c, intpp d, int size);
void extract(intpp matrix, int sz, intpp &A, intpp &B, intpp &C, intpp &D);
void dm(intpp m, int sz);

intpp Strassen(intpp a, intpp b, int sz) {
  intpp c = new intp[sz];
  if (sz == 1) {
    c[0] = new long long int[1];
    c[0][0] = a[0][0] * b[0][0];
  } else {
    intpp A, B, C, D, E, F, G, H;
    extract(a, sz, A, B, C, D);
    extract(b, sz, E, F, G, H);
    int quadSize = sz / 2;
    intpp FminusH = subtract(F, H, quadSize);
    intpp AplusB = add(A, B, quadSize);
    intpp CplusD = add(C, D, quadSize);
    intpp GminusE = subtract(G, E, quadSize);
    intpp AplusD = add(A, D, quadSize);
    intpp EplusH = add(E, H, quadSize);
    intpp BminusD = subtract(B, D, quadSize);
    intpp GplusH = add(G, H, quadSize);
    intpp AminusC = subtract(A, C, quadSize);
    intpp EplusF = add(E, F, quadSize);

    intpp p1 = Strassen(A, FminusH, quadSize);
    intpp p2 = Strassen(AplusB, H, quadSize);
    intpp p3 = Strassen(CplusD, E, quadSize);
    intpp p4 = Strassen(D, GminusE, quadSize);
    intpp p5 = Strassen(AplusD, EplusH, quadSize);
    intpp p6 = Strassen(BminusD, GplusH, quadSize);
    intpp p7 = Strassen(AminusC, EplusF, quadSize);

    intpp newA =
        add(add(p5, p4, quadSize), subtract(p6, p2, quadSize), quadSize);
    intpp newB = add(p1, p2, quadSize);
    intpp newC = add(p3, p4, quadSize);
    intpp newD =
        subtract(add(p1, p5, quadSize), add(p3, p7, quadSize), quadSize);

    c = combine(newA, newB, newC, newD, quadSize);

    dm(A, quadSize);
    dm(B, quadSize);
    dm(C, quadSize);
    dm(D, quadSize);
    dm(E, quadSize);
    dm(F, quadSize);
    dm(G, quadSize);
    dm(H, quadSize);
    dm(p1, quadSize);
    dm(p2, quadSize);
    dm(p3, quadSize);
    dm(p4, quadSize);
    dm(p5, quadSize);
    dm(p6, quadSize);
    dm(p7, quadSize);
    dm(newA, quadSize);
    dm(newB, quadSize);
    dm(newC, quadSize);
    dm(newD, quadSize);
  }
  return c;
}

int main() {
  uint32_t n, m, l, i, j;
  scanf("%d %d %d", &n, &m, &l);
  intpp a, b, c;
  uint32_t sz = pow(2, ceil(log2(max(n, max(m, l)))));
  a = new intp[sz];
  b = new intp[sz];
  for (i = 0; i < sz; ++i) {
    a[i] = new long long int[sz];
    b[i] = new long long int[sz];
    for (j = 0; j < sz; ++j)
      a[i][j] = b[i][j] = 0;
  }
  for (i = 0; i < n; ++i)
    for (j = 0; j < m; ++j)
      scanf("%lld", &a[i][j]);
  for (i = 0; i < m; ++i)
    for (j = 0; j < l; ++j)
      scanf("%lld", &b[i][j]);
  c = Strassen(a, b, sz);
  for (i = 0; i < n; ++i) {
    for (j = 0; j < l - 1; ++j)
      printf("%lld ", c[i][j]);
    printf("%lld\n", c[i][l - 1]);
  }
  // printf("\n");
}

intpp subtract(intpp a, intpp b, int sz) {
  intpp sub;
  sub = new intp[sz];
  for (int i = 0; i < sz; ++i) {
    sub[i] = new long long int[sz];
    for (int j = 0; j < sz; ++j)
      sub[i][j] = a[i][j] - b[i][j];
  }
  return sub;
}

intpp add(intpp a, intpp b, int sz) {
  intpp sum;
  sum = new intp[sz];
  for (int i = 0; i < sz; ++i) {
    sum[i] = new long long int[sz];
    for (int j = 0; j < sz; ++j)
      sum[i][j] = a[i][j] + b[i][j];
  }
  return sum;
}

void extract(intpp matrix, int sz, intpp &A, intpp &B, intpp &C, intpp &D) {
  sz /= 2;
  A = new intp[sz];
  B = new intp[sz];
  C = new intp[sz];
  D = new intp[sz];
  for (int i = 0; i < sz; ++i) {
    A[i] = new long long int[sz];
    B[i] = new long long int[sz];
    C[i] = new long long int[sz];
    D[i] = new long long int[sz];
    for (int j = 0; j < sz; ++j) {
      A[i][j] = matrix[i][j];
      B[i][j] = matrix[i][j + sz];
      C[i][j] = matrix[i + sz][j];
      D[i][j] = matrix[i + sz][j + sz];
    }
  }
}

intpp combine(intpp a, intpp b, intpp c, intpp d, int size) {
  intpp m = new intp[size * 2];
  for (int i = 0; i < size * 2; i++)
    m[i] = new long long int[size * 2];
  for (int i = 0; i < size; ++i) {
    for (int j = 0; j < size; ++j) {
      m[i][j] = a[i][j];
      m[i][j + size] = b[i][j];
      m[i + size][j] = c[i][j];
      m[i + size][j + size] = d[i][j];
    }
  }
  return m;
}

void dm(intpp m, int sz) {
  for (int i = 0; i < sz; i++)
    delete[] m[i];
  delete[] m;
}


Fixed submission:
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <vector>

using namespace std;

using intp = long long int *;
using intpp = long long int **;

intpp subtract(intpp a, intpp b, int sz);
intpp add(intpp a, intpp b, int sz);
intpp combine(intpp a, intpp b, intpp c, intpp d, int size);
void extract(intpp matrix, int sz, intpp &A, intpp &B, intpp &C, intpp &D);
void dm(intpp m, int sz);

intpp Strassen(intpp a, intpp b, int sz) {
  intpp c = new intp[sz];
  if (sz == 1) {
    c[0] = new long long int[1];
    c[0][0] = a[0][0] * b[0][0];
  } else {
    intpp A, B, C, D, E, F, G, H;
    extract(a, sz, A, B, C, D);
    extract(b, sz, E, F, G, H);
    int quadSize = sz / 2;
    intpp FminusH = subtract(F, H, quadSize);
    intpp AplusB = add(A, B, quadSize);
    intpp CplusD = add(C, D, quadSize);
    intpp GminusE = subtract(G, E, quadSize);
    intpp AplusD = add(A, D, quadSize);
    intpp EplusH = add(E, H, quadSize);
    intpp BminusD = subtract(B, D, quadSize);
    intpp GplusH = add(G, H, quadSize);
    intpp AminusC = subtract(A, C, quadSize);
    intpp EplusF = add(E, F, quadSize);

    intpp p1 = Strassen(A, FminusH, quadSize);
    intpp p2 = Strassen(AplusB, H, quadSize);
    intpp p3 = Strassen(CplusD, E, quadSize);
    intpp p4 = Strassen(D, GminusE, quadSize);
    intpp p5 = Strassen(AplusD, EplusH, quadSize);
    intpp p6 = Strassen(BminusD, GplusH, quadSize);
    intpp p7 = Strassen(AminusC, EplusF, quadSize);

    intpp newA =
        add(add(p5, p4, quadSize), subtract(p6, p2, quadSize), quadSize);
    intpp newB = add(p1, p2, quadSize);
    intpp newC = add(p3, p4, quadSize);
    intpp newD =
        subtract(add(p1, p5, quadSize), add(p3, p7, quadSize), quadSize);

    c = combine(newA, newB, newC, newD, quadSize);

    dm(A, quadSize);
    dm(B, quadSize);
    dm(C, quadSize);
    dm(D, quadSize);
    dm(E, quadSize);
    dm(F, quadSize);
    dm(G, quadSize);
    dm(H, quadSize);
    dm(p1, quadSize);
    dm(p2, quadSize);
    dm(p3, quadSize);
    dm(p4, quadSize);
    dm(p5, quadSize);
    dm(p6, quadSize);
    dm(p7, quadSize);
    dm(newA, quadSize);
    dm(newB, quadSize);
    dm(newC, quadSize);
    dm(newD, quadSize);
    dm(FminusH, quadSize);
    dm(AplusB, quadSize);
    dm(CplusD, quadSize);
    dm(GminusE, quadSize);
    dm(AplusD, quadSize);
    dm(EplusH, quadSize);
    dm(BminusD, quadSize);
    dm(GplusH, quadSize);
    dm(AminusC, quadSize);
    dm(EplusF, quadSize);
  }
  return c;
}

int main() {
  uint32_t n, m, l, i, j;
  scanf("%d %d %d", &n, &m, &l);
  intpp a, b, c;
  uint32_t sz = pow(2, ceil(log2(max(n, max(m, l)))));
  a = new intp[sz];
  b = new intp[sz];
  for (i = 0; i < sz; ++i) {
    a[i] = new long long int[sz];
    b[i] = new long long int[sz];
    for (j = 0; j < sz; ++j)
      a[i][j] = b[i][j] = 0;
  }
  for (i = 0; i < n; ++i)
    for (j = 0; j < m; ++j)
      scanf("%lld", &a[i][j]);
  for (i = 0; i < m; ++i)
    for (j = 0; j < l; ++j)
      scanf("%lld", &b[i][j]);
  c = Strassen(a, b, sz);
  for (i = 0; i < n; ++i) {
    for (j = 0; j < l - 1; ++j)
      printf("%lld ", c[i][j]);
    printf("%lld\n", c[i][l - 1]);
  }
  // printf("\n");
}

intpp subtract(intpp a, intpp b, int sz) {
  intpp sub;
  sub = new intp[sz];
  for (int i = 0; i < sz; ++i) {
    sub[i] = new long long int[sz];
    for (int j = 0; j < sz; ++j)
      sub[i][j] = a[i][j] - b[i][j];
  }
  return sub;
}

intpp add(intpp a, intpp b, int sz) {
  intpp sum;
  sum = new intp[sz];
  for (int i = 0; i < sz; ++i) {
    sum[i] = new long long int[sz];
    for (int j = 0; j < sz; ++j)
      sum[i][j] = a[i][j] + b[i][j];
  }
  return sum;
}

void extract(intpp matrix, int sz, intpp &A, intpp &B, intpp &C, intpp &D) {
  sz /= 2;
  A = new intp[sz];
  B = new intp[sz];
  C = new intp[sz];
  D = new intp[sz];
  for (int i = 0; i < sz; ++i) {
    A[i] = new long long int[sz];
    B[i] = new long long int[sz];
    C[i] = new long long int[sz];
    D[i] = new long long int[sz];
    for (int j = 0; j < sz; ++j) {
      A[i][j] = matrix[i][j];
      B[i][j] = matrix[i][j + sz];
      C[i][j] = matrix[i + sz][j];
      D[i][j] = matrix[i + sz][j + sz];
    }
  }
}

intpp combine(intpp a, intpp b, intpp c, intpp d, int size) {
  intpp m = new intp[size * 2];
  for (int i = 0; i < size * 2; i++)
    m[i] = new long long int[size * 2];
  for (int i = 0; i < size; ++i) {
    for (int j = 0; j < size; ++j) {
      m[i][j] = a[i][j];
      m[i][j + size] = b[i][j];
      m[i + size][j] = c[i][j];
      m[i + size][j + size] = d[i][j];
    }
  }
  return m;
}

void dm(intpp m, int sz) {
  for (int i = 0; i < sz; i++)
    delete[] m[i];
  delete[] m;
}