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

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
using namespace std;
#define MOD 1000000009
long long w, h, n;
struct Matrix {
  long long n, m[80][80];
  Matrix operator*(const Matrix &b) const {
    Matrix c;
    memset(c.m, 0, sizeof c.m);
    c.n = n;
    for (int i = 0; i < n; i++)
      for (int j = 0; j < n; j++)
        for (int k = 0; k < n; k++) {
          c.m[i][j] = (c.m[i][j] + (m[i][k] * b.m[k][j]) % MOD) % MOD;
        }
    return c;
  }
};
Matrix ones;
Matrix Pow(const Matrix &a, unsigned long long n) {
  Matrix t = ones, y = a;
  while (n) {
    if (n & 1)
      t = (t * y);
    y = (y * y);
    n /= 2;
  }
  return t;
}
Matrix A;
long long x[80];
long long k, p, q;
struct node {
  long long a, b;
};
node Pos[80];
int cmp(node a, node b) { return a.b < b.b; }
void get_x(Matrix a) {
  long long y[80];
  memset(y, 0, sizeof y);
  for (int i = 0; i < a.n; i++) {
    for (int j = 0; j < a.n; j++) {
      y[i] = (y[i] + (x[j] * a.m[i][j]) % MOD) % MOD;
    }
  }
  for (int i = 0; i < a.n; i++)
    x[i] = y[i];
}
int main() {
  int i, j;
  int d = 0;
  while (scanf("%lld%lld%lld", &w, &h, &n) != EOF) {
    memset(ones.m, 0, sizeof ones.m);
    for (i = 0; i < w; i++)
      ones.m[i][i] = 1;
    ones.n = w;
    for (i = 0; i < n; i++)
      scanf("%lld%lld", &Pos[i].a, &Pos[i].b);
    sort(Pos, Pos + n, cmp);
    if ((w == 0) && (h == 0) && (n == 0))
      return 0;
    memset(x, 0, sizeof x);
    x[0] = 1;
    memset(A.m, 0, sizeof A.m);
    A.n = w;
    A.m[0][0] = 1;
    A.m[0][1] = 1;
    for (i = 1; i < w; i++) {
      A.m[i][i] = 1;
      A.m[i][i - 1] = 1;
      A.m[i][i + 1] = 1;
    }
    k = 0;
    j = 0;
    while (j < n) {
      p = Pos[j].b - 1;
      if (p == k) {
        x[Pos[j].a - 1] = 0;
      } else {
        get_x(Pow(A, p - k));
        k = p;
        x[Pos[j].a - 1] = 0;
      }
      j++;
    }
    if (k < h - 1) {
      get_x(Pow(A, h - 1 - k));
    }
    printf("Case %d: %lld\\n", ++d, x[w - 1]);
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <iostream>
#include <set>
#include <stdio.h>
#include <string.h>
#include <vector>
using namespace std;
#define ll long long
const int mod = 1e9 + 7, N = 80;
ll n, m, bug;
struct Matrix {
  ll a[N][N];
  void org(int v) {
    memset(a, 0, sizeof(a));
    for (int i = 1; i <= n; i++) {
      a[i][i] = 1;
      if (v) {
        a[i][i - 1] = a[i][i + 1] = 1;
      }
    }
  }
  Matrix operator*(Matrix t) const {
    Matrix ans;
    for (int i = 1; i <= n; i++) {
      for (int j = 1; j <= n; j++) {
        ans.a[i][j] = 0;
        for (int k = 1; k <= n; k++)
          ans.a[i][j] = (ans.a[i][j] + a[i][k] * t.a[k][j] % mod) % mod;
      }
    }
    return ans;
  }
  Matrix got(ll x) {
    Matrix ans;
    ans.org(0);
    // ans.out();
    Matrix mul;
    mul.org(1);
    // mul.out();
    while (x) {
      if (x & 1)
        ans = ans * mul;
      x >>= 1;
      mul = (mul * mul);
    }
    // ans.out();
    return ans;
  }
  void out() {
    for (int i = 1; i <= n; i++) {
      for (int j = 1; j <= n; j++)
        printf("%lld ", a[i][j]);
      puts("");
    }
    puts("*******");
  }
};
set<int> g;
vector<pair<ll, ll>> ar;
int main() {
  int ca = 0;
  while (scanf("%lld%lld%lld", &n, &m, &bug), m + n + bug) {
    g.clear();
    ar.clear();
    for (int i = 0; i < bug; i++) {
      ll x, y;
      scanf("%lld%lld", &x, &y);
      // cout<<x<<" "<<y<<endl;
      // printf("%I64d %I64d\\n",x,y);
      ar.push_back(make_pair(x, y));
      g.insert(y);
    }
    g.erase(1);
    g.insert(m);
    ll a[N], b[N];
    memset(a, 0, sizeof(a));
    a[1] = 1;
    int now = 1;
    while (g.size()) {
      ll to = *(g.begin());
      // cout<<to<<endl;
      g.erase(g.begin());
      Matrix t;
      t = t.got(to - now);
      // t.out();
      for (int i = 1; i <= n; i++) {
        b[i] = 0;
        for (int j = 1; j <= n; j++)
          b[i] = (b[i] + t.a[i][j] * a[j]) % mod;
      }
      // for(int i=1;i<=n;i++) printf("%d ",b[i]);
      // puts("");
      swap(a, b);
      // for(int i=1;i<=n;i++) printf("%lld ",a[i]);
      // puts("");
      // cout<<ar[0].second<<endl;
      for (int i = 0; i < bug; i++)
        if (ar[i].second == to)
          a[ar[i].first] = 0;
      now = to;
      // for(int i=1;i<=n;i++) printf("%lld ",a[i]);
      // puts("");
    }
    printf("Case %d: %lld\\n", ++ca, a[n]);
  }
  return 0;
}