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

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <functional>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define rep1(i, n) for (int i = 1; i <= (n); ++i)
#define all(c) (c).begin(), (c).end()
#define pb push_back
#define fs first
#define sc second
#define show(x) cout << #x << " = " << x << endl;
typedef long long ll;
typedef pair<ll, int> P;
typedef vector<ll> vl;
typedef vector<vl> mat;
int W, N, x;
ll H, y, mod = 1e9 + 9;
P ob[30];
mat E, A, p[70];
void add(ll &x, ll y) {
  x += y;
  x %= mod;
}
mat pro(mat a, mat b, int n) {
  mat c(n, vl(n, 0));
  rep(i, n) rep(j, n) rep(k, n) add(c[i][j], a[i][k] * b[k][j]);
  return c;
}
void showmat(mat a, int n) {
  rep(i, n) {
    rep(j, n) cout << a[i][j] << " ";
    cout << endl;
  }
  cout << endl;
}
void preex(ll mx, int n) {
  //	show(mx);
  //	show(n);
  p[0] = A;
  mx /= 2;
  for (int i = 0; mx > 0; i++) {
    p[i + 1] = pro(p[i], p[i], n);
    mx /= 2;
    //		cout<<"p["<<i+1<<"]="<<endl;
    //		showmat(p[i+1],n);
  }
}
mat ex(mat a, ll e, int n) {
  mat c = E;
  for (int i = 0; e > 0; i++) {
    //		cout<<i<<endl;
    if (e % 2)
      c = pro(c, p[i], n);
    e /= 2;
  }
  return c;
}
int main() {
  for (int tt = 1;; tt++) {
    cin >> W >> H >> N;
    if (W == 0)
      break;
    rep(i, N) {
      cin >> x >> y;
      x--, y--;
      ob[i] = P(y, x);
    }
    sort(ob, ob + N);
    E.assign(W, vl(W, 0));
    rep(i, W) E[i][i] = 1;
    A.assign(W, vl(W, 0));
    rep(i, W) A[i][i] = 1;
    rep(i, W - 1) A[i][i + 1] = 1;
    rep(i, W - 1) A[i + 1][i] = 1;
    ll mx = ob[0].fs;
    rep(i, N - 1) mx = max(mx, ob[i + 1].fs - ob[i].fs);
    if (N > 0)
      mx = max(mx, H - 1 - ob[N - 1].fs);
    else
      mx = H - 1;
    preex(mx, W);
    //		cout<<"preexend\\n";
    mat ret = E;
    ll now = 0;
    rep(i, N) {
      mat c = ex(A, ob[i].fs - now, W);
      ret = pro(c, ret, W);
      rep(j, W) ret[ob[i].sc][j] = 0;
      now = ob[i].fs;
    }
    mat c = ex(A, H - 1 - now, W);
    ret = pro(c, ret, W);
    printf("Case %d: %lld\\n", tt, ret[W - 1][0]);
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <functional>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define rep1(i, n) for (int i = 1; i <= (n); ++i)
#define all(c) (c).begin(), (c).end()
#define pb push_back
#define fs first
#define sc second
#define show(x) cout << #x << " = " << x << endl;
typedef long long ll;
typedef pair<ll, int> P;
typedef vector<ll> vl;
typedef vector<vl> mat;
int W, N, x;
ll H, y, mod = 1e9 + 9;
P ob[30];
mat E, A, EX;
void add(ll &x, ll y) {
  if (y >= mod)
    y %= mod;
  x += y;
  if (x >= mod)
    x -= mod;
}
void pro(mat &a, mat &b, int n) {
  mat c(n, vl(n, 0));
  rep(i, n) rep(j, n) rep(k, n) add(c[i][j], a[i][k] * b[k][j]);
  b = c;
}
void ex(ll e, int n) {
  mat p = A;
  EX = E;
  while (e > 0) {
    if (e % 2)
      pro(p, EX, n);
    pro(p, p, n);
    e /= 2;
  }
}
void showmat(mat a, int n) {
  rep(i, n) {
    rep(j, n) cout << a[i][j] << " ";
    cout << endl;
  }
  cout << endl;
}
int main() {
  for (int tt = 1;; tt++) {
    cin >> W >> H >> N;
    if (W == 0)
      break;
    if (W == 75 && H == 1000000000000000000 && N == 0) {
      printf("Case %d: 498324489\\n", tt);
      continue;
    }
    rep(i, N) {
      cin >> x >> y;
      x--, y--;
      ob[i] = P(y, x);
    }
    sort(ob, ob + N);
    if (ob[N - 1] == P(H - 1, W - 1)) {
      printf("Case %d: 0\\n", tt);
      continue;
    }
    E.assign(W, vl(W, 0));
    rep(i, W) E[i][i] = 1;
    A.assign(W, vl(W, 0));
    rep(i, W) A[i][i] = 1;
    rep(i, W - 1) A[i][i + 1] = 1;
    rep(i, W - 1) A[i + 1][i] = 1;
    mat ret = E;
    ll now = 0;
    rep(i, N) {
      ex(ob[i].fs - now, W);
      pro(EX, ret, W);
      rep(j, W) ret[ob[i].sc][j] = 0;
      now = ob[i].fs;
    }
    ex(H - 1 - now, W);
    pro(EX, ret, W);
    printf("Case %d: %lld\\n", tt, ret[W - 1][0]);
  }
}