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

#include <iostream>
using namespace std;

long long kt = 10000000000000;

struct longnum {
  long long n[3];
  double d;
};

longnum add(longnum a, longnum b) {
  int i;
  longnum c;
  c.d = 0;
  for (i = 0; i < 3; i++) {
    c.n[i] = a.n[i] + b.n[i];
    if (c.n[i] >= kt) {
      c.n[i] -= kt;
      b.n[i + 1]++;
    }
  }
  return c;
}

longnum mul(longnum a, int b) {
  int i;
  long long h = 0, d;
  longnum c;
  c.d = 0;
  for (i = 0; i < 3; i++) {
    d = a.n[i] * b + h;
    c.n[i] = d % kt;
    h = d / kt;
  }
  return c;
}

longnum div(longnum a, int b) {
  int i, k;
  for (i = 2; i >= 0; i--) {
    k = a.n[i] % b;
    a.n[i] /= b;
    if (i > 0)
      a.n[i - 1] += k * kt;
    else
      a.d += k;
  }
  a.d /= b;
  return a;
}

void set(longnum &a, int b) {
  a.n[2] = a.n[1] = 0;
  a.n[0] = b;
  a.d = 0;
}

struct masu {
  int in, ia;
  longnum g[2][5101];
};

masu m[51];

int main() {
  int c, x, y, z, n, e, a, i, j, k, d, g, v[4], s[2][51], sn[2], f, f2, f3,
      cl[51], mx;
  longnum h, t;
  double ans;
  while (cin >> x >> y >> z && x != 0) {
    ans = 0;
    mx = 0;
    f3 = 0;
    for (i = 0; i <= y; i++)
      for (j = 0; j <= 5000; j++) {
        set(m[i].g[0][j], 0);
        set(m[i].g[1][j], 0);
        m[i].in = 0;
      }
    for (i = 0; i < x; i++)
      cin >> v[i];
    for (i = 0; i < z; i++) {
      cin >> n >> e >> a;
      m[n].in = e;
      m[n].ia = a;
    }
    sn[0] = 1;
    sn[1] = 0;
    s[0][0] = 0;
    f = 0;
    c = 0;
    set(m[0].g[f][0], 1);
    while (true) {
      for (i = 0; i <= y; i++)
        cl[i] = 0;
      for (i = 0; i < sn[f]; i++)
        for (j = 0; j < x; j++) {
          k = s[f][i] + v[j];
          if (k > y)
            k = y;
          if (m[k].in == 1)
            k += m[k].ia;
          if (k > y)
            k = y;
          cl[k] = 1;
        }
      for (i = 1; i <= y; i++)
        if (cl[i] == 1)
          for (j = 0; j <= c * 100 + 100; j++)
            set(m[i].g[1 - f][j], 0);
      for (i = 0; i < sn[f]; i++) {
        if (s[f][i] == y)
          continue;
        for (j = 0; j < x; j++) {
          k = s[f][i] + v[j];
          f2 = 0;
          if (k > y)
            k = y;
          if (m[k].in == 1) {
            k += m[k].ia;
            f2 = 1;
          }
          if (k > y)
            k = y;
          if (k > f3)
            f3 = k;
          d = 0;
          for (g = 0; g < sn[1 - f]; g++)
            if (s[1 - f][g] == k)
              d = 1;
          if (d == 0) {
            s[1 - f][sn[1 - f]] = k;
            sn[1 - f]++;
          }
          for (e = 0; e <= mx; e++) {
            d = 0;
            if (m[k].in == 2 && f2 == 0) {
              d = 1;
              m[k].g[1 - f][e + m[k].ia] =
                  add(m[k].g[1 - f][e + m[k].ia], m[s[f][i]].g[f][e]);
            }
            if (m[k].in == 3 && f2 == 0) {
              d = 1;
              if (e - m[k].ia < 0)
                m[k].g[1 - f][0] = add(m[k].g[1 - f][0], m[s[f][i]].g[f][e]);
              else
                m[k].g[1 - f][e - m[k].ia] =
                    add(m[k].g[1 - f][e - m[k].ia], m[s[f][i]].g[f][e]);
            }
            if (d == 0)
              m[k].g[1 - f][e] = add(m[k].g[1 - f][e], m[s[f][i]].g[f][e]);
          }
        }
      }
      sn[f] = 0;
      f = 1 - f;
      c++;
      mx = 0;
      for (i = 0; i <= f3; i++)
        if (m[i].in == 2)
          mx += m[i].ia;
      set(t, 0);
      for (i = 1; i <= c * 100; i++) {
        h = mul(m[y].g[f][i], i);
        t = add(t, h);
      }
      for (i = 0; i < c; i++)
        t = div(t, x);
      ans = ans + t.n[0] + t.d;
      if (sn[f] == 1 && s[f][0] == y)
        break;
    }
    cout << (int)ans << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <iostream>
using namespace std;

long long kt = 10000000000000;

struct longnum {
  long long n[3];
  double d;
};

longnum add(longnum a, longnum b) {
  int i;
  longnum c;
  c.d = 0;
  for (i = 0; i < 3; i++) {
    c.n[i] = a.n[i] + b.n[i];
    if (c.n[i] >= kt) {
      c.n[i] -= kt;
      b.n[i + 1]++;
    }
  }
  return c;
}

longnum mul(longnum a, int b) {
  int i;
  long long h = 0, d;
  longnum c;
  c.d = 0;
  for (i = 0; i < 3; i++) {
    d = a.n[i] * b + h;
    c.n[i] = d % kt;
    h = d / kt;
  }
  return c;
}

longnum div(longnum a, int b) {
  int i, k;
  for (i = 2; i >= 0; i--) {
    k = a.n[i] % b;
    a.n[i] /= b;
    if (i > 0)
      a.n[i - 1] += k * kt;
    else
      a.d += k;
  }
  a.d /= b;
  return a;
}

void set(longnum &a, int b) {
  a.n[2] = a.n[1] = 0;
  a.n[0] = b;
  a.d = 0;
}

struct masu {
  int in, ia;
  longnum g[2][5001];
};

masu m[51];

int main() {
  int c, x, y, z, n, e, a, i, j, k, d, g, v[4], s[2][51], sn[2], f, f2, f3,
      cl[51], mx;
  longnum h, t;
  double ans;
  while (cin >> x >> y >> z && x != 0) {
    ans = 0;
    mx = 0;
    f3 = 0;
    for (i = 0; i <= y; i++)
      for (j = 0; j <= 4900; j++) {
        set(m[i].g[0][j], 0);
        set(m[i].g[1][j], 0);
        m[i].in = 0;
      }
    for (i = 0; i < x; i++)
      cin >> v[i];
    for (i = 0; i < z; i++) {
      cin >> n >> e >> a;
      m[n].in = e;
      m[n].ia = a;
    }
    sn[0] = 1;
    sn[1] = 0;
    s[0][0] = 0;
    f = 0;
    c = 0;
    set(m[0].g[f][0], 1);
    while (true) {
      for (i = 0; i <= y; i++)
        cl[i] = 0;
      for (i = 0; i < sn[f]; i++)
        for (j = 0; j < x; j++) {
          k = s[f][i] + v[j];
          if (k > y)
            k = y;
          if (m[k].in == 1)
            k += m[k].ia;
          if (k > y)
            k = y;
          cl[k] = 1;
        }
      for (i = 0; i <= y; i++)
        if (cl[i] == 1)
          for (j = 0; j <= 4900; j++)
            set(m[i].g[1 - f][j], 0);
      for (i = 0; i < sn[f]; i++) {
        if (s[f][i] == y)
          continue;
        for (j = 0; j < x; j++) {
          k = s[f][i] + v[j];
          f2 = 0;
          if (k > y)
            k = y;
          if (m[k].in == 1) {
            k += m[k].ia;
            f2 = 1;
          }
          if (k > y)
            k = y;
          if (k > f3)
            f3 = k;
          d = 0;
          for (g = 0; g < sn[1 - f]; g++)
            if (s[1 - f][g] == k)
              d = 1;
          if (d == 0) {
            s[1 - f][sn[1 - f]] = k;
            sn[1 - f]++;
          }
          for (e = 0; e <= mx; e++) {
            d = 0;
            if (m[k].in == 2 && f2 == 0) {
              d = 1;
              m[k].g[1 - f][e + m[k].ia] =
                  add(m[k].g[1 - f][e + m[k].ia], m[s[f][i]].g[f][e]);
            }
            if (m[k].in == 3 && f2 == 0) {
              d = 1;
              if (e - m[k].ia < 0)
                m[k].g[1 - f][0] = add(m[k].g[1 - f][0], m[s[f][i]].g[f][e]);
              else
                m[k].g[1 - f][e - m[k].ia] =
                    add(m[k].g[1 - f][e - m[k].ia], m[s[f][i]].g[f][e]);
            }
            if (d == 0)
              m[k].g[1 - f][e] = add(m[k].g[1 - f][e], m[s[f][i]].g[f][e]);
          }
        }
      }
      sn[f] = 0;
      f = 1 - f;
      c++;
      mx = 0;
      for (i = 0; i < f3; i++)
        if (m[i].in == 2)
          mx += m[i].ia;
      set(t, 0);
      set(h, 0);
      for (i = 1; i <= 4900; i++) {
        h = mul(m[y].g[f][i], i);
        t = add(t, h);
      }
      for (i = 0; i < c; i++)
        t = div(t, x);
      ans = ans + t.n[0] + t.d;
      if (sn[f] == 1 && s[f][0] == y)
        break;
    }
    cout << (int)ans << endl;
  }
  return 0;
}