Problem p03749 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;
typedef long long LL;
const int maxn = 1e5 + 10, mod = 1e9 + 7;

int read() {
  int x = 0, f = 1;
  char c = getchar();
  while (!isdigit(c)) {
    if (c == '-')
      f = 0;
    c = getchar();
  }
  while (isdigit(c)) {
    x = (x << 3) + (x << 1) + (c ^ 48);
    c = getchar();
  }
  return f ? x : -x;
}

struct mat {
  int a[3][3];
  mat() {
    for (int i = 0; i <= 2; ++i)
      for (int j = 0; j <= 2; ++j)
        a[i][j] = 0;
  }
  mat operator*(const mat &A) const {
    mat tmp;
    for (int i = 0; i <= 2; ++i)
      for (int j = 0; j <= 2; ++j)
        for (int k = 0; k <= 2; ++k)
          (tmp.a[i][j] += (LL)a[i][k] * A.a[k][j] % mod) %= mod;
    return tmp;
  }
} w, now, spj;

void gao(int p) {
  if (p <= 0)
    return;
  mat x = w;
  // int fg = 0;
  // int fg = 1;
  while (p) {
    if (p & 1)
      now = x * now;
    p >>= 1;
    x = x * x;
  }
}

int s[maxn];

int main() {
#ifndef ONLINE_JUDGE
  freopen("a.in", "r", stdin);
  freopen("a.out", "w", stdout);
#endif

  int n = read(), m = read();
  for (int i = 1; i <= m; ++i)
    s[i] = read() + 1;
  int tmp[3][3] = {{1, 0, 1}, {2, 1, 2}, {1, 1, 2}};
  swap(w.a, tmp);
  int Tmp[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
  swap(now.a, Tmp);
  int TMP[3][3] = {{1, 0, 0}, {2, 1, 0}, {1, 1, 1}};
  swap(spj.a, TMP);
  int pos = 1;
  for (int i = 1; i <= m; ++i) {
    gao(s[i] - pos);
    pos = s[i] + 1;
    now = spj * now;
  }
  gao(n - pos + 1);
  // now = w * now;
  // now = w * w * w * w * w * now;
  /*
  for(int i = 0; i <= 2; ++i)
  {
          for(int j = 0; j <= 2; ++j)
                  cout << now.a[i][j] << ' ';
          cout << endl;
  }*/
  // now = w * now;
  cout << now.a[2][0] << endl;

  return 0;
}

Fixed submission:
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;
typedef long long LL;
const int maxn = 1e5 + 10, mod = 1e9 + 7;

int read() {
  int x = 0, f = 1;
  char c = getchar();
  while (!isdigit(c)) {
    if (c == '-')
      f = 0;
    c = getchar();
  }
  while (isdigit(c)) {
    x = (x << 3) + (x << 1) + (c ^ 48);
    c = getchar();
  }
  return f ? x : -x;
}

struct mat {
  int a[3][3];
  mat() {
    for (int i = 0; i <= 2; ++i)
      for (int j = 0; j <= 2; ++j)
        a[i][j] = 0;
  }
  mat operator*(const mat &A) const {
    mat tmp;
    for (int i = 0; i <= 2; ++i)
      for (int j = 0; j <= 2; ++j)
        for (int k = 0; k <= 2; ++k)
          (tmp.a[i][j] += (LL)a[i][k] * A.a[k][j] % mod) %= mod;
    return tmp;
  }
} w, now, spj;

void gao(int p) {
  if (p <= 0)
    return;
  mat x = w;
  // int fg = 0;
  // int fg = 1;
  while (p) {
    if (p & 1)
      now = x * now;
    p >>= 1;
    x = x * x;
  }
}

int s[maxn];

int main() {

  int n = read(), m = read();
  for (int i = 1; i <= m; ++i)
    s[i] = read() + 1;
  int tmp[3][3] = {{1, 0, 1}, {2, 1, 2}, {1, 1, 2}};
  swap(w.a, tmp);
  int Tmp[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
  swap(now.a, Tmp);
  int TMP[3][3] = {{1, 0, 0}, {2, 1, 0}, {1, 1, 1}};
  swap(spj.a, TMP);
  int pos = 1;
  for (int i = 1; i <= m; ++i) {
    gao(s[i] - pos);
    pos = s[i] + 1;
    now = spj * now;
  }
  gao(n - pos + 1);
  // now = w * now;
  // now = w * w * w * w * w * now;
  /*
  for(int i = 0; i <= 2; ++i)
  {
          for(int j = 0; j <= 2; ++j)
                  cout << now.a[i][j] << ' ';
          cout << endl;
  }*/
  // now = w * now;
  cout << now.a[2][0] << endl;

  return 0;
}