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

#include <cassert>
#include <iostream>
#include <string>
#include <vector>
using namespace std;

int deg(char c) {
  if (c >= 'A')
    return 10 + c - 'A';
  return c - '0';
}

long long int gcd(long long int a, long long int b) {
  return b == 0 ? a : gcd(b, a % b);
}

long long int lcm(long long int a, long long int b) {
  if (a < b) {
    return a * (b / gcd(a, b));
  } else {
    return b * (a / gcd(a, b));
  }
}

struct Phrase {
  vector<int> vf;
  Phrase() {}
  Phrase(const string &s) {
    for (int i = 0; i < s.length(); i += 2) {
      char c1 = s[i];
      if (i + 1 >= s.length())
        return;
      char c2 = s[i + 1];
      vf.push_back((deg(c1) * 0x10 + deg(c2)));
    }
  }
  Phrase merge(const Phrase &t) {
    Phrase ret;
    long long int len = vf.size();
    long long int tlen = t.vf.size();
    long long int LCM = lcm(len, tlen);
    for (int k = 0; k < LCM; ++k) {
      int s = 0;
      if (k % (LCM / len) == 0)
        s += vf[k / (LCM / len)];
      if (k % (LCM / tlen) == 0)
        s += t.vf[k / (LCM / tlen)];
      ret.vf.push_back(s);
    }
    return ret;
  }
  void eraseExtraZeroes() {
    vector<int> non_zero_pos;
    for (int i = 1; i < vf.size(); ++i) {
      if (vf[i] != 0)
        non_zero_pos.push_back(i);
    }
    long long int min_gcd = vf.size();
    for (int i = 0; i < non_zero_pos.size(); ++i) {
      min_gcd = gcd(non_zero_pos[i], min_gcd);
    }
    if (min_gcd > 1) {
      int n = 0;
      for (int i = 0; i < vf.size(); i += min_gcd) {
        for (int j = 1; j < min_gcd; ++j) {
          vf[i + j] = -1;
        }
      }
    }
    Phrase t;
    for (int i = 0; i < vf.size(); ++i)
      if (vf[i] >= 0)
        t.vf.push_back(vf[i]);
    *this = t;
  }
  void print() {
    for (int i = 0; i < vf.size(); ++i) {
      printf("%02X", vf[i]);
    }
    putchar('\\n');
  }
};

int main() {
  int T;
  cin >> T;
  for (int tc = 1; tc <= T; ++tc) {
    int N;
    string s;
    bool toocomplex = false;
    Phrase P;

    cin >> N;
    if (N == 0)
      break;

    int left = N;
    for (int i = 0; i < N; ++i) {
      cin >> s;
      Phrase t(s);
      --left;

      t.eraseExtraZeroes();
      if (P.vf.size() == 0)
        P = t;
      else
        P = P.merge(t);
      P.eraseExtraZeroes();

      if (2 * P.vf.size() > 2048) {
        toocomplex = true;
        break;
      }
    }
    for (int i = 0; i < left; ++i) {
      cin >> s;
    }

    if (toocomplex) {
      printf("Too complex.\\n");
    } else {
      P.print();
    }
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <cassert>
#include <iostream>
#include <string>
#include <vector>
using namespace std;

int deg(char c) {
  if (c >= 'A')
    return 10 + c - 'A';
  return c - '0';
}

long long int gcd(long long int a, long long int b) {
  return b == 0 ? a : gcd(b, a % b);
}

long long int lcm(long long int a, long long int b) {
  if (a < b) {
    return a * (b / gcd(a, b));
  } else {
    return b * (a / gcd(a, b));
  }
}

struct Phrase {
  vector<int> vf;
  Phrase() {}
  Phrase(const string &s) {
    for (int i = 0; i < s.length(); i += 2) {
      char c1 = s[i];
      char c2 = s[i + 1];
      vf.push_back((deg(c1) * 0x10 + deg(c2)));
    }
  }
  Phrase merge(const Phrase &t) {
    Phrase ret;
    long long int len = vf.size();
    long long int tlen = t.vf.size();
    long long int LCM = lcm(len, tlen);
    for (int k = 0; k < LCM; ++k) {
      int s = 0;
      if (k % (LCM / len) == 0)
        s += vf[k / (LCM / len)];
      if (k % (LCM / tlen) == 0)
        s += t.vf[k / (LCM / tlen)];
      ret.vf.push_back(s);
    }
    return ret;
  }
};

void EraseExtraZeroes(Phrase &sum) {
  int L = 0;

  for (int i = (int)sum.vf.size() - 1; i >= 0; --i) {
    if (sum.vf[i] == 0) {
      ++L;
    } else
      break;
  }
  if (L == sum.vf.size()) {
    sum.vf.clear();
    sum.vf.push_back(0);
    return;
  } else {
    ++L;
    while (L > 1) {
      bool un = false;
      for (int i = 0; i < sum.vf.size(); i += L) {
        for (int j = 1; j < L; ++j) {
          if (i + j > sum.vf.size()) {
            un = true;
            break;
          }
          if (sum.vf[i + j] != 0) {
            un = true;
            break;
          }
        }
      }
      if (!un) {
        for (int i = 0; i < sum.vf.size(); i += L) {
          for (int j = 1; j < L; ++j) {
            sum.vf[i + j] = -1;
          }
        }
        break;
      }
      --L;
    }
  }

  Phrase tmp;
  for (int i = 0; i < sum.vf.size(); ++i) {
    if (sum.vf[i] >= 0) {
      tmp.vf.push_back(sum.vf[i]);
    }
  }
  if (tmp.vf.size() == 0) {
    tmp.vf.push_back(0);
  }
  sum = tmp;
  return;
}

int main() {
  int T;
  scanf("%d", &T);
  for (int tc = 1; tc <= T; ++tc) {
    int N;
    bool toocomplex = false;
    Phrase P;

    scanf("%d", &N);
    if (N == 0)
      break;

    string s;
    getline(cin, s);
    for (int i = 0; i < N; ++i) {
      getline(cin, s);
      int len;
      Phrase t(s);

      if (s.length() == 0)
        t.vf.push_back(0);

      if (P.vf.size() == 0) {
        P = t;
      } else {
        P = P.merge(t);
      }

      while (true) {
        len = P.vf.size();
        EraseExtraZeroes(P);
        if (len == P.vf.size())
          break;
      }

      if (2 * P.vf.size() > 2048) {
        toocomplex = true;
        break;
      }
    }

    if (P.vf.size() == 0) {
      P.vf.push_back(0);
    }
    if (toocomplex) {
      printf("Too complex.\\n");
    } else {
      for (int i = 0; i < P.vf.size(); ++i) {
        printf("%02X", P.vf[i]);
      }
      putchar('\\n');
    }
  }
  return 0;
}