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

#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

long long H, W, N, x[100], y[100], ID, mod = 1000000009;
long long pre[64][80][80];
vector<long long> A, P;

void precount() {
  for (int i = 0; i < 64; i++) {
    for (int j = 0; j < 80; j++) {
      for (int k = 0; k < 80; k++)
        pre[i][j][k] = 0;
    }
  }
  for (int i = 0; i < H; i++) {
    if (i - 1 >= 0)
      pre[0][i][i - 1] = 1;
    pre[0][i][i] = 1;
    if (i + 1 < H)
      pre[0][i][i + 1] = 1;
  }
  for (int t = 0; t < 63; t++) {
    for (int i = 0; i < H; i++) {
      for (int k = 0; k < H; k++) {
        for (int l = 0; l < H; l++) {
          pre[t + 1][i][l] += pre[t][i][k] * pre[t][k][l];
          pre[t + 1][i][l] %= mod;
        }
      }
    }
  }
}
void solve(long long rep) {
  for (int i = 0; i < 62; i++) {
    if ((rep / (1LL << i)) % 2 == 0)
      continue;
    vector<long long> B;
    B.resize(H, 0);
    for (int j = 0; j < H; j++) {
      for (int k = 0; k < H; k++) {
        B[k] += P[j] * pre[i][j][k];
        B[k] %= mod;
      }
    }
    P = B;
  }
}

int main() {
  while (true) {
    ID++;
    cin >> H >> W >> N;
    A.clear();
    P.clear();
    if (H == 0)
      break;
    for (int i = 1; i <= N; i++) {
      cin >> x[i] >> y[i];
      x[i]--;
      A.push_back(y[i]);
    }
    A.push_back(W);
    sort(A.begin(), A.end());
    A.erase(unique(A.begin(), A.end()), A.end());
    precount();
    P.resize(H, 0);
    P[0] = 1;
    long long cx = 1;
    for (int i = 0; i < A.size(); i++) {
      solve(A[i] - cx);
      cx = A[i];
      for (int j = 1; j <= N; j++) {
        if (y[j] == A[i])
          P[x[j]] = 0;
      }
    }
    cout << "Case " << ID << ": " << P[H - 1] << endl;
  }
  return 0;
}


Error: TLE

Fixed submission:

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

//-------------------------------------------------LIBRARY OF
//MATRIX----------------------------------------------------------
struct Matrix {
  vector<vector<long long>> x;
};
void resize_(Matrix &a, long long H, long long W) {
  a.x.resize(H);
  for (long long i = 0; i < H; i++)
    a.x[i].resize(W);
  for (long long i = 0; i < H; i++) {
    for (long long j = 0; j < W; j++)
      a.x[i][j] = 0;
  }
}
inline Matrix multiple(Matrix a, Matrix b, long long m) {
  Matrix c;
  resize_(c, a.x.size(), b.x[0].size());
  for (int i = 0; i < c.x.size(); i++) {
    for (int j = 0; j < c.x[0].size(); j++) {
      for (int k = 0; k < b.x.size(); k++) {
        c.x[i][j] += a.x[i][k] * b.x[k][j];
        c.x[i][j] %= m;
      }
    }
  }
  return c;
}
inline Matrix power(Matrix a, long long r, long long m) {
  Matrix G, H;
  G = a;
  long long cnt = 0;
  H = a;
  int upper = 0;
  for (int i = 0; i < 63; i++) {
    if ((r / (1LL << i)) % 2 == 01)
      upper = i;
  }
  for (long long i = 0; i < a.x.size(); i++) {
    for (long long j = 0; j < a.x[0].size(); j++) {
      H.x[i][j] = 0;
    }
  }
  for (long long i = 0; i < a.x.size(); i++) {
    H.x[i][i] = 1;
  }
  for (long long i = 0; i < upper; i++) {
    if (i >= 1)
      G = multiple(G, G, m);
    if ((r / (1LL << i)) % 2 == 0)
      continue;
    H = multiple(H, G, m);
  }
  return H;
}
int main() {
  int cnt = 0;
  while (true) {
    long long H, W, N;
    cnt++;
    cin >> H >> W >> N;
    if (H == 0 && W == 0 && N == 0)
      break;
    vector<long long> vec1;
    vector<long long> vec2[50];
    for (int i = 0; i < 50; i++)
      vec2[i].clear();
    for (int i = 0; i < N; i++) {
      long long XX, YY;
      cin >> XX >> YY;
      XX--;
      YY--;
      bool flag = false;
      for (int j = 0; j < vec1.size(); j++) {
        if (vec1[j] == YY) {
          flag = true;
          vec2[j].push_back(XX);
        }
      }
      if (flag == false) {
        vec2[vec1.size()].push_back(XX);
        vec1.push_back(YY);
      }
    }
    Matrix ans;
    resize_(ans, H, 1);
    ans.x[0][0] = 1;
    Matrix norm;
    resize_(norm, H, H);
    for (int i = 0; i < H; i++) {
      if (i > 0)
        norm.x[i][i - 1] = 1;
      norm.x[i][i] = 1;
      if (i < H - 1)
        norm.x[i][i + 1] = 1;
    }
    long long R1 = 0;
    for (int i = 0; i < vec1.size(); i++) {
      ans =
          multiple(power(norm, vec1[i] - R1, 1000000007LL), ans, 1000000007LL);
      for (int j = 0; j < vec2[i].size(); j++) {
        ans.x[vec2[i][j]][0] = 0;
      }
      R1 = vec1[i];
    }
    ans = multiple(power(norm, (W - 1) - R1, 1000000007LL), ans, 1000000007LL);
    cout << "Case " << cnt << ": " << ans.x[H - 1][0] << endl;
  }
  return 0;
}