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

#include <algorithm>
#include <stdio.h>
#include <string.h>
using namespace std;
long long mod = 1000000009;
int x[32];
long long y[32];
int mat[63][75][75];
int val[75][75];
int tmp[75][75];
int sen[75][75];
long long now[110];
long long to[110];
long long z[110];
int v[110];

int main() {
  int tc = 0;
  int a, c;
  long long b;
  while (scanf("%d%lld%d", &a, &b, &c), a) {
    bool dame = false;
    for (int i = 0; i < c; i++) {
      scanf("%d%lld", x + i, y + i);
      x[i]--;
      y[i]--;
      z[i] = y[i];
      if (x[i] == a - 1 && y[i] == b - 1) {
        dame = true;
      }
    }
    if (dame) {
      printf("Case %d: 0\\n", ++tc);
      continue;
    }
    std::sort(z, z + c);
    z[c] = b - 1;
    for (int i = 0; i < a; i++)
      for (int j = 0; j < a; j++)
        sen[i][j] = 0;
    for (int i = 0; i < a; i++) {
      sen[i][i]++;
      if (i)
        sen[i - 1][i]++;
      if (i < a - 1)
        sen[i + 1][i]++;
    }
    for (int i = 0; i < a; i++) {
      for (int j = 0; j < a; j++)
        mat[0][i][j] = sen[i][j];
    }
    for (int i = 1; i < 63; i++) {
      for (int j = 0; j < a; j++)
        for (int k = 0; k < a; k++)
          mat[i][j][k] = 0;
      for (int j = 0; j < a; j++)
        for (int k = 0; k < a; k++)
          for (int l = 0; l < a; l++)
            mat[i][j][k] = (mat[i][j][k] +
                            (long long)mat[i - 1][j][l] * mat[i - 1][l][k]) %
                           mod;
    }
    for (int i = 0; i < a; i++)
      now[i] = 0;
    now[0] = 1;
    int at = 0;
    long long last = 0;
    for (int i = 0; i <= c; i++) {
      if (i && z[i] == z[i - 1])
        continue;
      for (int j = 0; j < a; j++)
        for (int k = 0; k < a; k++)
          val[j][k] = 0;
      for (int j = 0; j < a; j++)
        val[j][j] = 1;
      long long d = z[i] - last;
      for (int s = 0; s < 63; s++) {
        if (d & (1LL << s)) {
          for (int j = 0; j < a; j++)
            for (int k = 0; k < a; k++)
              tmp[j][k] = 0;
          for (int l = 0; l < a; l++)
            for (int j = 0; j < a; j++)
              if (mat[j][l])
                for (int k = 0; k < a; k++) {
                  if (val[l][k])
                    tmp[j][k] =
                        (tmp[j][k] + (long long)mat[s][j][l] * val[l][k]) % mod;
                }
          for (int j = 0; j < a; j++)
            for (int k = 0; k < a; k++)
              val[j][k] = tmp[j][k];
        }
      }
      for (int j = 0; j < a; j++) {
        to[j] = 0;
      }
      for (int j = 0; j < a; j++) {
        for (int k = 0; k < a; k++)
          to[j] = (to[j] + now[k] * val[j][k]) % mod;
      }
      for (int j = 0; j < a; j++)
        now[j] = to[j];
      if (i == c)
        break;
      last = z[i] + 1;
      for (int j = 0; j < a; j++)
        v[j] = 0;
      for (int j = 0; j < c; j++)
        if (z[i] == y[j])
          v[x[j]] = 1;
      for (int j = 0; j < a; j++)
        to[j] = 0;
      for (int j = 0; j < a; j++) {
        if (v[j])
          continue;
        for (int k = -1; k <= 1; k++) {
          if (0 <= j + k && j + k < a)
            to[j + k] = (to[j + k] + now[j]) % mod;
        }
      }
      for (int j = 0; j < a; j++)
        now[j] = to[j];
    }
    printf("Case %d: %lld\\n", ++tc, now[a - 1]);
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <stdio.h>
#include <string.h>
using namespace std;
long long mod = 1000000009;
int x[32];
long long y[32];
int mat[75][75];
int val[75][75];
int tmp[75][75];
int sen[75][75];
long long now[110];
long long to[110];
long long z[110];
int v[110];
int main() {
  int tc = 0;
  int a, c;
  long long b;
  while (scanf("%d%lld%d", &a, &b, &c), a) {
    bool dame = false;
    for (int i = 0; i < c; i++) {
      scanf("%d%lld", x + i, y + i);
      x[i]--;
      y[i]--;
      z[i] = y[i];
      if (x[i] == a - 1 && y[i] == b - 1) {
        dame = true;
      }
    }
    if (dame) {
      printf("Case %d: 0\\n", ++tc);
      continue;
    }
    std::sort(z, z + c);
    z[c] = b - 1;
    for (int i = 0; i < a; i++)
      for (int j = 0; j < a; j++)
        sen[i][j] = 0;
    for (int i = 0; i < a; i++) {
      sen[i][i]++;
      if (i)
        sen[i - 1][i]++;
      if (i < a - 1)
        sen[i + 1][i]++;
    }
    for (int i = 0; i < a; i++)
      now[i] = 0;
    now[0] = 1;
    int at = 0;
    long long last = 0;
    for (int i = 0; i <= c; i++) {
      if (i && z[i] == z[i - 1])
        continue;
      for (int j = 0; j < a; j++)
        for (int k = 0; k < a; k++)
          mat[j][k] = sen[j][k];
      for (int j = 0; j < a; j++)
        for (int k = 0; k < a; k++)
          val[j][k] = 0;
      for (int j = 0; j < a; j++)
        val[j][j] = 1;
      long long d = z[i] - last;
      while (d) {
        if (d & 1) {
          //	memset(tmp,0,sizeof(tmp));
          for (int j = 0; j < a; j++)
            for (int k = 0; k < a; k++)
              tmp[j][k] = 0;
          for (int l = 0; l < a; l++)
            for (int j = 0; j < a; j++)
              if (mat[j][l])
                for (int k = 0; k < a; k++) {
                  if (val[l][k])
                    tmp[j][k] =
                        (tmp[j][k] + (long long)mat[j][l] * val[l][k]) % mod;
                }
          for (int j = 0; j < a; j++)
            for (int k = 0; k < a; k++)
              val[j][k] = tmp[j][k];
        }
        // memset(tmp,0,sizeof(tmp));
        for (int j = 0; j < a; j++)
          for (int k = 0; k < a; k++)
            tmp[j][k] = 0;
        for (int l = 0; l < a; l++)
          for (int j = 0; j < a; j++)
            if (mat[j][l])
              for (int k = 0; k < a; k++) {
                if (mat[l][k])
                  tmp[j][k] =
                      (tmp[j][k] + (long long)mat[j][l] * mat[l][k]) % mod;
              }
        for (int j = 0; j < a; j++)
          for (int k = 0; k < a; k++)
            mat[j][k] = tmp[j][k];
        d /= 2;
      }
      for (int j = 0; j < a; j++) {
        to[j] = 0;
      }
      for (int j = 0; j < a; j++) {
        for (int k = 0; k < a; k++)
          to[j] = (to[j] + now[k] * val[j][k]) % mod;
      }
      for (int j = 0; j < a; j++)
        now[j] = to[j];
      if (i == c)
        break;
      last = z[i] + 1;
      for (int j = 0; j < a; j++)
        v[j] = 0;
      for (int j = 0; j < c; j++)
        if (z[i] == y[j])
          v[x[j]] = 1;
      for (int j = 0; j < a; j++)
        to[j] = 0;
      for (int j = 0; j < a; j++) {
        if (v[j])
          continue;
        for (int k = -1; k <= 1; k++) {
          if (0 <= j + k && j + k < a)
            to[j + k] = (to[j + k] + now[j]) % mod;
        }
      }
      for (int j = 0; j < a; j++)
        now[j] = to[j];
    }
    printf("Case %d: %lld\\n", ++tc, now[a - 1]);
  }
}