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

#include <bits/stdc++.h>
#define int long long
#define N 11
#define H (1e18)
#define W 76
using namespace std;
typedef pair<int, int> P;
const int INF = 1LL << 55;
const int mod = (1e9) + 9;
const double EPS = 1e-8;
const double PI = 6.0 * asin(0.5);
template <class T> T Max(T &a, T b) { return a = max(a, b); }
template <class T> T Min(T &a, T b) { return a = min(a, b); }
typedef vector<int> vec;
typedef vector<vec> mat;
int w, h, n;

mat mul(const mat &a, const mat &b) {
  mat res(w, vec(w, 0));
  for (int i = 0; i < w; i++)
    for (int j = 0; j < w; j++)
      for (int k = 0; k < w; k++)
        res[i][j] = (res[i][j] + a[i][k] * b[k][j] % mod) % mod;

  return res;
}

vec calc(const mat &a, const vec &b) {
  vec res(w, 0);
  for (int i = 0; i < w; i++)
    for (int j = 0; j < w; j++)
      res[i] = (res[i] + b[j] * a[j][i] % mod) % mod;
  return res;
}

mat doubling(mat x, int y) {
  mat res(w, vec(w, 0));
  for (int i = 0; i < w; i++)
    res[i][i] = 1;

  while (y) {
    if (y % 2)
      res = mul(res, x);
    y /= 2;
    x = mul(x, x);
  }
  return res;
}

signed main() {
  int t = 0;
  while (1) {
    cin >> w >> h >> n;
    if (w == 0 && h == 0 && n == 0)
      break;
    priority_queue<P, vector<P>, greater<P>> ng;
    int flg = 0;
    for (int i = 0; i < n; i++) {
      int x, y;
      cin >> x >> y;
      x--, y--;
      flg |= (x == w - 1) && (y == h - 1);
      flg |= (x == 0) && (y == 0);
      if (y >= h)
        i--, n--;
      else if (y == 0)
        i--, n--;
      else
        ng.push(P(y, x));
    }
    ng.push(P(h - 1, -1));

    vector<int> ans(w, 0);
    ans[0] = flg == 0;

    int height = 0;
    mat num(w, vec(w, 0));
    for (int i = 0; i < w; i++)
      for (int j = i - 1; j <= i + 1; j++)
        if (j >= 0 && j < w)
          num[i][j] = 1;

    while (!ng.empty()) {
      int nheight = ng.top().first;
      int d = nheight - height;
      mat res = doubling(num, d);
      ans = calc(res, ans);
      height = nheight;

      while (!ng.empty() && nheight == ng.top().first) {
        if (ng.top().second >= 0)
          ans[ng.top().second] = 0;
        ng.pop();
      }
    }

    assert(height == h - 1);
    cout << "Case " << ++t << ": " << ans[w - 1] << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define int long long
#define N 11
#define H (1e18)
#define W 76
using namespace std;
typedef pair<int, int> P;
const int INF = 1LL << 55;
const int mod = (1e9) + 9;
const double EPS = 1e-8;
const double PI = 6.0 * asin(0.5);
template <class T> T Max(T &a, T b) { return a = max(a, b); }
template <class T> T Min(T &a, T b) { return a = min(a, b); }
typedef vector<int> vec;
typedef vector<vec> mat;
int w, h, n;

mat mul(const mat &a, const mat &b) {
  mat res(w, vec(w, 0));
  for (int i = 0; i < w; i++)
    for (int j = 0; j < w; j++)
      for (int k = 0; k < w; k++)
        res[i][j] = (res[i][j] + a[i][k] * b[k][j] % mod) % mod;

  return res;
}

vec calc(const mat &a, const vec &b) {
  vec res(w, 0);
  for (int i = 0; i < w; i++)
    for (int j = 0; j < w; j++)
      res[i] = (res[i] + b[j] * a[j][i] % mod) % mod;
  return res;
}

mat doubling(mat x, int y) {
  mat res(w, vec(w, 0));
  for (int i = 0; i < w; i++)
    res[i][i] = 1;

  while (y) {
    if (y % 2)
      res = mul(res, x);
    y /= 2;
    x = mul(x, x);
  }
  return res;
}

signed main() {
  int t = 0;
  while (1) {
    cin >> w >> h >> n;
    if (w == 0 && h == 0 && n == 0)
      break;
    priority_queue<P, vector<P>, greater<P>> ng;
    int flg = 0;
    for (int i = 0; i < n; i++) {
      int x, y;
      cin >> x >> y;
      x--, y--;
      flg |= (x == w - 1) && (y == h - 1);
      flg |= (x == 0) && (y == 0);
      if (y >= h)
        i--, n--;
      else if (y == 0)
        i--, n--;
      else
        ng.push(P(y, x));
    }
    ng.push(P(h - 1, -1));

    vector<int> ans(w, 0);
    ans[0] = flg == 0;

    int height = 0;
    while (!ng.empty()) {
      mat num(w, vec(w, 0));
      for (int i = 0; i < w; i++)
        for (int j = i - 1; j <= i + 1; j++)
          if (j >= 0 && j < w)
            num[i][j] = 1;

      int nheight = ng.top().first;
      int d = nheight - height;
      num = doubling(num, d);
      ans = calc(num, ans);
      height = nheight;

      while (!ng.empty() && nheight == ng.top().first)
        if (ng.top().second > 0)
          ans[ng.top().second] = 0;
      ng.pop();
    }
    assert(height == h - 1);
    cout << "Case " << ++t << ": " << ans[w - 1] << endl;
  }
  return 0;
}