Problem p01228 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;
typedef unsigned char uc;
struct R {
  uc notes[1024];
  int num;
  void push(const uc &note) { notes[num++] = note; }
};

R rolls[8];
char hexmap[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
                   '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};

int gcd_of(int a, int b) {
  while (a != b) {
    if (a > b)
      a -= b;
    else
      b -= a;
  }
  return a;
}

int lcm_of(const int &a, const int &b) { return a * b / gcd_of(a, b); }

int main() {
  int t;
  cin >> t;
  while (t--) {
    int n;
    cin >> n;
    for (int i = 0; i < n; i++) {
      // load
      char buff[2049];
      cin >> buff;
      char *p = buff;
      auto &r = rolls[i];
      r.num = 0;
      while (*p != 0) {
        r.push((*p - '0') * 16 + (*(p + 1) - '0'));
        p += 2;
      }

      // comp
      int gcd = r.num;
      int clen = 1;
      for (int j = 1; j < r.num; j++) {
        if (r.notes[j] == 0) {
          clen++;
        } else {
          gcd = gcd_of(gcd, clen);
          clen = 1;
          if (gcd == 1)
            break;
        }
      }
      gcd = gcd_of(gcd, clen);
      if (gcd != 1) {
        r.num /= gcd;
        for (int j = 0; j < r.num; j++)
          r.notes[j] = r.notes[j * gcd];
      }
    }
    int lcm = rolls[0].num;

    for (int i = 1; i < n; i++) {
      lcm = lcm_of(lcm, rolls[i].num);
    }

    if (lcm > 1024) {
      cout << "Too complex.";
    } else {
      // combine
      int m[8];
      for (int i = 0; i < n; i++)
        m[i] = lcm / rolls[i].num;
      for (int i = 0; i < lcm; i++) {
        uc v = 0;
        for (int j = 0; j < n; j++) {
          if (i % m[j] == 0)
            v |= rolls[j].notes[i / m[j]];
        }
        cout << hexmap[v / 16] << hexmap[v % 16];
      }
    }
    cout << endl;
  }
  return 0;
}

Fixed submission:
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;
typedef unsigned char uc;
struct R {
  uc notes[1024];
  int num;
  void push(const uc &note) { notes[num++] = note; }
};

R rolls[8];
char hexmap[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
                   '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};

int gcd_of(int a, int b) {
  while (a != b) {
    if (a > b)
      a -= b;
    else
      b -= a;
  }
  return a;
}

int lcm_of(const int &a, const int &b) { return a * b / gcd_of(a, b); }

int main() {
  int t;
  cin >> t;
  while (t--) {
    int n;
    cin >> n;
    for (int i = 0; i < n; i++) {
      // load
      char buff[2049];
      cin >> buff;
      char *p = buff;
      auto &r = rolls[i];
      r.num = 0;
      while (*p != 0) {
        r.push((*p - '0') * 16 + (*(p + 1) - '0'));
        p += 2;
      }

      // comp
      int gcd = r.num;
      int clen = 1;
      for (int j = 1; j < r.num; j++) {
        if (r.notes[j] == 0) {
          clen++;
        } else {
          gcd = gcd_of(gcd, clen);
          clen = 1;
          if (gcd == 1)
            break;
        }
      }
      gcd = gcd_of(gcd, clen);
      if (gcd != 1) {
        r.num /= gcd;
        for (int j = 0; j < r.num; j++)
          r.notes[j] = r.notes[j * gcd];
      }
    }
    int lcm = rolls[0].num;

    for (int i = 1; i < n; i++) {
      lcm = lcm_of(lcm, rolls[i].num);
      if (lcm > 1024)
        break; // for overflow
    }

    if (lcm > 1024) {
      cout << "Too complex.";
    } else {
      // combine
      int m[8];
      for (int i = 0; i < n; i++)
        m[i] = lcm / rolls[i].num;
      for (int i = 0; i < lcm; i++) {
        uc v = 0;
        for (int j = 0; j < n; j++) {
          if (i % m[j] == 0)
            v |= rolls[j].notes[i / m[j]];
        }
        cout << hexmap[v / 16] << hexmap[v % 16];
      }
    }
    cout << endl;
  }
  return 0;
}