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

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef vector<ll> vec;
typedef vector<vec> mat;
#define MAX 77

ll mod = 1e9 + 9;

ll H, W, N;
ll B[MAX][MAX];

ll tmp[MAX][MAX];
void mul(ll a[MAX][MAX], ll b[MAX][MAX]) {
  for (int i = 0; i < W; i++)
    for (int j = 0; j < W; j++)
      tmp[i][j] = 0;

  for (int i = 0; i < W; i++) {
    for (int k = 0; k < W; k++) {
      for (int j = 0; j < W; j++) {
        tmp[i][j] += (a[i][k] * b[k][j]);
        tmp[i][j] %= mod;
      }
    }
  }
  for (int i = 0; i < W; i++)
    for (int j = 0; j < W; j++)
      a[i][j] = tmp[i][j];
}

ll nans[MAX];
ll ans[MAX];

ll met[MAX][MAX];
void mpow(ll a[MAX][MAX], ll n) {
  while (n) {
    if (n & 1LL) {
      for (int i = 0; i < W; i++) {
        nans[i] = 0;
        for (int j = 0; j < W; j++) {
          nans[i] += (a[i][j] * ans[j]);
          nans[i] %= mod;
        }
      }

      for (int i = 0; i < W; i++)
        ans[i] = nans[i];
    }
    mul(a, a);
    n = (n >> 1LL);
  }
  for (int i = 0; i < W; i++)
    for (int j = 0; j < W; j++)
      a[i][j] = met[i][j];
}

int main() {
  for (int tc = 1;; tc++) {
    scanf("%lld %lld %lld", &W, &H, &N);

    if (W == 0 && H == 0 && N == 0)
      break;

    vector<ll> v;
    unordered_map<ll, vector<ll>> G;

    memset(ans, 0, sizeof(ans));
    ans[0] = 1;

    memset(B, 0, sizeof(B));
    for (int i = 0; i < W; i++) {
      if (i + 1 < W)
        B[i][i + 1]++;
      B[i][i]++;
      if (i - 1 >= 0)
        B[i][i - 1]++;
    }

    for (int i = 0; i < N; i++) {
      ll x, y;
      cin >> x >> y;
      v.push_back(y);
      G[y].push_back(x);
    }

    v.push_back(H);
    sort(v.begin(), v.end());
    v.erase(unique(v.begin(), v.end()), v.end());

    ll C[MAX][MAX];

    ll last = 1;
    for (int I = 0; I < (int)v.size(); I++) {
      ll h = v[I];
      ll dist = h - last;

      for (int i = 0; i < W; i++)
        for (int j = 0; j < W; j++)
          C[i][j] = B[i][j];

      mpow(C, dist);

      last = h;

      if (G.count(h) == 0)
        continue;
      for (int j : G[h]) {
        ans[j - 1] = 0;
      }
    }
    cout << "Case " << tc << ": " << ans[W - 1] << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef vector<ll> vec;
typedef vector<vec> mat;
#define MAX 77

ll mod = 1e9 + 9;

ll H, W, N;
ll B[MAX][MAX];

ll tmp[MAX][MAX];
void mul(ll a[MAX][MAX], ll b[MAX][MAX]) {
  for (int i = 0; i < W; i++)
    for (int j = 0; j < W; j++)
      tmp[i][j] = 0;

  for (int k = 0; k < W; k++) {
    for (int i = 0; i < W; i++) {
      for (int j = 0; j < W; j++) {

        tmp[i][j] += (a[i][k] * b[k][j]);
        tmp[i][j] %= mod;
      }
    }
  }
  for (int i = 0; i < W; i++)
    for (int j = 0; j < W; j++)
      a[i][j] = tmp[i][j];
}

ll met[MAX][MAX];
void mpow(ll a[MAX][MAX], ll n) {
  for (int i = 0; i < W; i++)
    for (int j = 0; j < W; j++)
      met[i][j] = (i == j ? 1 : 0);

  while (n) {
    if (n & 1LL)
      mul(met, a);
    mul(a, a);
    n = (n >> 1LL);
  }
  for (int i = 0; i < W; i++)
    for (int j = 0; j < W; j++)
      a[i][j] = met[i][j];
}

ll ans[MAX];
int main() {
  for (int tc = 1;; tc++) {
    scanf("%lld %lld %lld", &W, &H, &N);

    if (W == 0 && H == 0 && N == 0)
      break;

    vector<ll> v;
    unordered_map<ll, vector<ll>> G;

    memset(ans, 0, sizeof(ans));
    ans[0] = 1;

    memset(B, 0, sizeof(B));
    for (int i = 0; i < W; i++) {
      if (i + 1 < W)
        B[i][i + 1]++;
      B[i][i]++;
      if (i - 1 >= 0)
        B[i][i - 1]++;
    }

    for (int i = 0; i < N; i++) {
      ll x, y;
      cin >> x >> y;
      v.push_back(y);
      G[y].push_back(x);
    }

    v.push_back(H);
    sort(v.begin(), v.end());
    v.erase(unique(v.begin(), v.end()), v.end());

    ll C[MAX][MAX];
    ll nans[MAX];

    ll last = 1;
    for (int I = 0; I < (int)v.size(); I++) {
      ll h = v[I];
      ll dist = h - last;

      for (int i = 0; i < W; i++)
        for (int j = 0; j < W; j++)
          C[i][j] = B[i][j];

      mpow(C, dist);

      for (int i = 0; i < W; i++) {
        nans[i] = 0;
        for (int j = 0; j < W; j++) {
          nans[i] += (C[i][j] * ans[j]);
          nans[i] %= mod;
        }
      }

      for (int i = 0; i < W; i++)
        ans[i] = nans[i];

      last = h;

      if (G.count(h) == 0)
        continue;
      for (int j : G[h]) {
        ans[j - 1] = 0;
      }
    }
    cout << "Case " << tc << ": " << ans[W - 1] << endl;
  }
  return 0;
}