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

#include <bits/stdc++.h>
#define int long long
#define r(i, n) for (int i = 0; i < n; i++)
using namespace std;
typedef pair<int, int> P;
typedef vector<vector<int>> mat;
int h, w, n;
inline void mat_mul(mat &A, mat &B, int M = 1000000009) {
  mat ret(w, vector<int>(w));
  for (int i = 0; i < w; ++i) {
    for (int j = 0; j < w; ++j) {
      ret[i][j] = 0;
      for (int k = 0; k < w; ++k) {
        ret[i][j] += (A[i][k] * B[k][j]) % M;
        ret[i][j] %= M;
      }
    }
  }
  A = ret;
}

inline void mat_pow(mat &A, int N, int M = 1000000009) {
  mat ret(A.size(), vector<int>(A.size(), 0)), t = A;
  for (int i = 0; i < A.size(); ++i)
    ret[i][i] = 1;
  int k = 0;
  while (N > 0) {
    if (N & 1) {
      mat_mul(ret, t, M);
    }
    mat_mul(t, t, M);
    N >>= 1;
  }
  A = ret;
}

mat XXX;

void init() {
  mat res(w, vector<int>(w, 0));
  for (int i = 0; i < w; i++) {
    for (int j = 0; j < w; j++) {
      if (i == j) {
        if (i)
          res[i - 1][j] = 1;
        res[i][j] = 1;
        if (i != w - 1)
          res[i + 1][j] = 1;
      }
    }
  }
  XXX = res;
}

inline mat make_mat(vector<int> &V) {
  mat res = XXX;
  for (int i = 0; i < V.size(); i++) {
    for (int j = 0; j < w; j++) {
      res[j][V[i]] = 0;
    }
  }
  return res;
}

signed main() {
  init();
  int cnt = 0;
  while (cin >> w >> h >> n, w) {
    init();
    cout << "Case " << (++cnt) << ": ";
    vector<P> v;
    vector<int> v1;
    r(i, n) {
      int x, y;
      cin >> x >> y;
      x--;
      y--;
      if (y == 0)
        v1.push_back(x);
      else
        v.push_back(P(y, x));
    }
    v.push_back(P(1e18 + 1, 0));
    int y = 0;
    sort(v.begin(), v.end());
    mat A(w, vector<int>(w, 0));
    A[0][0] = 1;
    r(i, v1.size()) A[v1[i]][v1[i]] = 0;
    for (int i = 0; i < v.size(); i++) {
      int s = v[i].first;
      int c = s - y;
      vector<int> vs, kara;
      vs.push_back(v[i].second);
      while (v[i].first == v[i + 1].first) {
        vs.push_back(v[i + 1].second);
        i++;
      }
      mat B = make_mat(vs);
      mat C = make_mat(kara);
      if (s == 1e18 + 1) {
        c = (h - 1) - y;
        if (c) {
          mat_pow(C, c);
          mat_mul(A, C);
        }
        break;
      }
      if (c > 1) {
        mat_pow(C, c - 1);
        mat_mul(A, C);
      }
      mat_mul(A, B);
      y = s;
    }
    int ans = 0;
    r(i, w) ans = (ans + A[i][w - 1]) % 1000000009;
    cout << ans << endl;
  }
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define int long long
#define r(i, n) for (int i = 0; i < n; i++)
using namespace std;
typedef pair<int, int> P;
typedef vector<vector<int>> mat;
int h, w, n;
inline void mat_mul(mat &A, mat &B, int M = 1000000009) {
  mat ret(w, vector<int>(w));
  for (int i = 0; i < w; ++i) {
    for (int j = 0; j < w; ++j) {
      ret[i][j] = 0;
      for (int k = 0; k < w; ++k) {
        ret[i][j] += (A[i][k] * B[k][j]) % M;
        ret[i][j] %= M;
      }
    }
  }
  A = ret;
}

void mat_pow(mat &A, int N, int M = 1000000009) {
  mat ret(A.size(), vector<int>(A.size(), 0)), t = A;
  for (int i = 0; i < A.size(); ++i)
    ret[i][i] = 1;
  int k = 0;
  while (N > 0) {
    if (N & 1) {
      mat_mul(ret, t, M);
    }
    mat_mul(t, t, M);
    N >>= 1;
  }
  A = ret;
}

mat XXX;

void init() {
  mat res(w, vector<int>(w, 0));
  for (int i = 0; i < w; i++) {
    for (int j = 0; j < w; j++) {
      if (i == j) {
        if (i)
          res[i - 1][j] = 1;
        res[i][j] = 1;
        if (i != w - 1)
          res[i + 1][j] = 1;
      }
    }
  }
  XXX = res;
}

inline mat make_mat(vector<int> &V) {
  mat res = XXX;
  for (int i = 0; i < V.size(); i++) {
    for (int j = 0; j < w; j++) {
      res[j][V[i]] = 0;
    }
  }
  return res;
}

signed main() {
  init();
  int cnt = 0;
  while (cin >> w >> h >> n, w) {
    init();
    cout << "Case " << (++cnt) << ": ";
    vector<P> v;
    vector<int> v1;
    r(i, n) {
      int x, y;
      cin >> x >> y;
      x--;
      y--;
      if (y == 0)
        v1.push_back(x);
      else
        v.push_back(P(y, x));
    }
    v.push_back(P(1e18 + 1, 0));
    int y = 0;
    sort(v.begin(), v.end());
    mat A(w, vector<int>(w, 0));
    A[0][0] = 1;
    r(i, v1.size()) A[v1[i]][v1[i]] = 0;
    for (int i = 0; i < v.size(); i++) {
      int s = v[i].first;
      int c = s - y;
      vector<int> vs, kara;
      vs.push_back(v[i].second);
      while (v[i].first == v[i + 1].first) {
        vs.push_back(v[i + 1].second);
        i++;
      }
      mat B = make_mat(vs);
      mat C = make_mat(kara);
      if (s == 1e18 + 1) {
        c = (h - 1) - y;
        if (c) {
          mat_pow(C, c);
          mat_mul(A, C);
        }
        break;
      }
      if (c > 1) {
        mat_pow(C, c - 1);
        mat_mul(A, C);
      }
      mat_mul(A, B);
      y = s;
    }
    int ans = 0;
    r(i, w) ans = (ans + A[i][w - 1]) % 1000000009;
    cout << ans << endl;
  }
}