Problem:
G: 運命力 - Destiny Draw -
問題
Mr. D はカードゲームで勝負をすることになった。
このカードゲームでは、
N
枚のカードの山を用いる。
また、山のカードには、上から順に
1, 2, 3,
...
, N
の番号がついている。
D で始まるものすべてを背負う彼に敗北は許されないが、不幸にも Mr. D はカードゲームが不得手である。
そこで、自分が引くカードをコントロールすることで勝利を手にすることにした。
Mr. D は
K
種類のシャッフルが可能である。
K
種類のうち
i
番目のシャッフルでは上から
a_i
枚目から
a_i+b_i − 1
枚目までのちょうど
b_i
枚を引き抜き、上に重ねる。
i
番目のシャッフルを
1
回するとき、それぞれ
t_i
秒を要する。
ちょうど
T
秒のシャッフルの後、一番上のカードを
C
にする方法は何通りあるか。 数が多くなる可能性があるので、
10^9+7
で割った余りを出力せよ。
入力形式
入力は次の形式で与えられる。
N
K
C
T
a_1
b_1
t_1
a_2
b_2
t_2
...
a_K
b_K
t_K
N
は整数で
2 \≤ N \≤ 40
を満たす。
K
は整数で
1 \≤ K \≤ \frac{N (N+1)}{2}
を満たす
C
は整数で
1 \≤ C \≤ N
を満たす
T
は整数で
1 \≤ T \≤ 1,000,000
を満たす
a_i
(
i = 1, 2,
...
, K
) は整数で
1 \≤ a_i \≤ N
を満たす
b_i
(
i = 1, 2,
...
, K
) は整数で
1 \≤ b_i \≤ N − a_i + 1
を満たす
a_i = a_j
かつ
b_i = b_j
を満たすとき
i = j
に限定される
t_i
は整数で
1 \≤ t_i \≤ 5
を満たす
出力形式
答えを
10^9+7
で割った余りを一行で出力せよ。
入力例1
4 1 1 6
3 2 3
出力例1
1
入力例2
4 1 1 5
3 2 3
出力例2
0
入力例3
6 2 2 5
1 2 1
2 5 3
出力例3
3
ちょうど
5
秒で一番上のカードを
2
にする方法は以下の
3
通りである。
1→1→2
1→2→1
2→1→1
入力例4
6 8 3 10
1 4 5
1 3 3
1 6 5
1 2 2
1 1 4
2 5 1
4 3 1
2 1 3
出力例4
3087

Submitted solutions:

code_snippet: // AOJ #2778 Destiny Draw
// 2025.3.2

#include <bits/stdc++.h>
using namespace std;
const long long MOD = 1000000007;

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);

    int n, K, C, T;
    cin >> n >> K >> C >> T;
    vector<vector<vector<long long>>> A(6, vector<vector<long long>>(n, vector<long long>(n, 0)));
    for (int i = 0; i < K; i++){
        int a, b, t;
        cin >> a >> b >> t;
        int a0 = a - 1;
        for (int x = 0; x < n; x++){
            int y;
            if (x >= a0 && x < a0 + b) y = x - a0;
            else if (x < a0) y = x + b;
            else y = x;
            A[t][y][x] = (A[t][y][x] + 1) % MOD;
        }
    }
    int m = min(T, 5);
    vector<vector<long long>> dp(m + 1, vector<long long>(n, 0));
    dp[0][C - 1] = 1;
    for (int t = 1; t <= m; t++){
        for (int cost = 1; cost <= min(t, 5); cost++){
            for (int i = 0; i < n; i++){
                long long s = 0;
                for (int j = 0; j < n; j++) s = (s + A[cost][i][j] * dp[t - cost][j]) % MOD;
                dp[t][i] = (dp[t][i] + s) % MOD;
            }
        }
    }
    if (T <= 5){
        cout << dp[T][0] << endl;
        return 0;
    }
    int d = 5 * n;
    vector<vector<long long>> M(d, vector<long long>(d, 0));
    for (int j = 0; j < 5; j++){
        for (int i = 0; i < n; i++){
            for (int k = 0; k < n; k++) M[i][j * n + k] = A[j + 1][i][k] % MOD;
        }
    }
    for (int j = 1; j < 5; j++){
        for (int i = 0; i < n; i++) M[j * n + i][(j - 1) * n + i] = 1;
    }
    vector<long long> X(d, 0);
    for (int i = 0; i < n; i++){
        X[i] = dp[5][i];
        X[n + i] = dp[4][i];
        X[2 * n + i] = dp[3][i];
        X[3 * n + i] = dp[2][i];
        X[4 * n + i] = dp[1][i];
    }
    auto mulMat = [&](const vector<vector<long long>> &B, const vector<vector<long long>> &C) -> vector<vector<long long>> {
        vector<vector<long long>> R(d, vector<long long>(d, 0));
        for (int i = 0; i < d; i++){
            for (int k = 0; k < d; k++){
                if (B[i][k])
                    for (int j = 0; j < d; j++) R[i][j] = (R[i][j] + B[i][k] * C[k][j]) % MOD;
            }
        }
        return R;
    };
    auto mulVec = [&](const vector<vector<long long>> &B, const vector<long long> &v) -> vector<long long> {
        vector<long long> r(d, 0);
        for (int i = 0; i < d; i++){
            for (int j = 0; j < d; j++) r[i] = (r[i] + B[i][j] * v[j]) % MOD;
        }
        return r;
    };
    auto mpow = [&](long long p) -> vector<vector<long long>> {
        vector<vector<long long>> R(d, vector<long long>(d, 0));
        for (int i = 0; i < d; i++) R[i][i] = 1;
        vector<vector<long long>> B = M;
        while (p){
            if (p & 1) R = mulMat(R, B);
            B = mulMat(B, B);
            p >>= 1;
        }
        return R;
    };
    vector<vector<long long>> Mexp = mpow(T - 5);
    vector<long long> Y = mulVec(Mexp, X);
    cout << Y[0] % MOD << endl;
    return 0;
}
accuracy: 1
time_ms: 240
memory_kb: 4424
final_rank: 4

code_snippet: #include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
using namespace std;
using std::cout;
using std::cin;
using std::endl;
using ll=long long;
using ld=long double;
ll ILL=2167167167167167167;
const int INF=2100000000;
const ll mod=1e9+7;
#define rep(i,a) for (ll i=0;i<a;i++)
#define all(p) p.begin(),p.end()
template<class T> using _pq = priority_queue<T, vector<T>, greater<T>>;
template<class T> ll LB(vector<T> &v,T a){return lower_bound(v.begin(),v.end(),a)-v.begin();}
template<class T> ll UB(vector<T> &v,T a){return upper_bound(v.begin(),v.end(),a)-v.begin();}
template<class T> bool chmin(T &a,const T &b){if(a>b){a=b;return 1;}else return 0;}
template<class T> bool chmax(T &a,const T &b){if(a<b){a=b;return 1;}else return 0;}
template<class T> void So(vector<T> &v) {sort(v.begin(),v.end());}
template<class T> void Sore(vector<T> &v) {sort(v.begin(),v.end(),[](T x,T y){return x>y;});}
void yneos(bool a){if(a) cout<<"Yes\n"; else cout<<"No\n";}
template<class T> void vec_out(vector<T> &p){for(int i=0;i<(int)(p.size());i++){if(i) cout<<" ";cout<<p[i];}cout<<"\n";}
template<class T> T min(vector<T> &a){assert(!a.empty());T ans=a[0];for(auto &x:a) chmin(ans,x);return ans;}
template<class T> T max(vector<T> &a){assert(!a.empty());T ans=a[0];for(auto &x:a) chmax(ans,x);return ans;}



template<class T>
using square_matrix=std::vector<std::vector<T>>;
template<class T,T (*add_op)(T,T),T(*add_e)(),T (*mul_op)(T,T),T(*mul_e)()>
square_matrix<T> mul_matrix(square_matrix<T> l,square_matrix<T> r){
	int n=l.size();
	assert((int)l[0].size()==n&&(int)r.size()==n&&(int)r[0].size()==n);
	square_matrix<T> val(n,std::vector<T>(n,add_e()));
	for(int i=0;i<n;i++) for(int j=0;j<n;j++) for(int k=0;k<n;k++){
		val[i][k]=add_op(val[i][k],mul_op(l[i][j],r[j][k]));
	}
	return val;
}
template<class T,T (*add_op)(T,T),T(*add_e)(),T (*mul_op)(T,T),T(*mul_e)()>
square_matrix<T> pow_matrix(square_matrix<T> l,long long times){
	int n=l.size();
	square_matrix<T> val(n,std::vector<T>(n,add_e()));
	for(int i=0;i<n;i++) val[i][i]=mul_e();
	while(times){
		if(times&1){
			val=mul_matrix<T,add_op,add_e,mul_op,mul_e>(val,l);
		}
		l=mul_matrix<T,add_op,add_e,mul_op,mul_e>(l,l);
		times>>=1;
	}
	return val;
}

using mat_F=ll;
mat_F add_op(mat_F a,mat_F b){
	return (a+b)%mod;
}
mat_F add_e(){
	return 0;
}
mat_F mul_op(mat_F a,mat_F b){
	return (a*b)%mod;
}
mat_F mul_e(){
	return 1;
}
#define calc mat_F,add_op,add_e,mul_op,mul_e


void solve();
// oddloop
int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	
	int t=1;
	//cin>>t;
	rep(i,t) solve();
}

void solve(){
	ll N,K,C,T;
	cin>>N>>K>>C>>T;
	vector<vector<ll>> p(N*5,vector<ll>(N*5));
	rep(i,N*4) p[i][i+N]=1;
	rep(i,K){
		ll a,b,t;
		cin>>a>>b>>t;
		a--;t--;
		rep(j,N){
			if(j<a) p[N*t+j][j+b]++;
			else if(j<a+b) p[N*t+j][j-a]++;
			else p[N*t+j][j]++;
		}
	}
	auto base=pow_matrix<calc>(p,T);
	//rep(i,N*5) vec_out(base[i]);
	cout<<base[C-1][0]<<"\n";
}
accuracy: 1
time_ms: 430
memory_kb: 4960
final_rank: 7

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

template <class T>
struct Matrix {
  vector<vector<T>> A;
  Matrix() {}
  Matrix(size_t m, size_t n) : A(m, vector<T>(n, 0)) {}
  Matrix(size_t n) : A(n, vector<T>(n, 0)) {}
  size_t height() const { return (A.size()); }
  size_t width() const { return (A[0].size()); }
  inline const vector<T> &operator[](int k) const { return (A.at(k)); }
  inline vector<T> &operator[](int k) { return (A.at(k)); }
  static Matrix E(size_t n) {
    Matrix mat(n);
    for (int i = 0; i < n; ++i) mat[i][i] = 1;
    return (mat);
  }
  Matrix &operator+=(const Matrix &B) {
    size_t m = height(), n = width();
    assert(m == B.height() && n == B.width());
    for (int i = 0; i < m; ++i)
      for (int j = 0; j < n; ++j) (*this)[i][j] += B[i][j];
    return (*this);
  }
  Matrix &operator-=(const Matrix &B) {
    size_t m = height(), n = width();
    assert(m == B.height() && n == B.width());
    for (int i = 0; i < m; ++i)
      for (int j = 0; j < n; ++j) (*this)[i][j] -= B[i][j];
    return (*this);
  }
  Matrix &operator*=(const Matrix &B) {
    size_t m = height(), n = B.width(), p = width();
    assert(p == B.height());
    vector<vector<T>> C(m, vector<T>(n, 0));
    for (int i = 0; i < m; ++i)
      for (int k = 0; k < p; ++k) {
        T tmp = (*this)[i][k];
        for (int j = 0; j < n; ++j) C[i][j] += tmp * B[k][j];
      }
    A.swap(C);
    return (*this);
  }
  Matrix &operator^=(long long k) {
    Matrix B = Matrix::E(height());
    while (k) {
      if (k & 1) B *= *this;
      *this *= *this;
      k >>= 1;
    }
    A.swap(B.A);
    return (*this);
  }

  Matrix operator+(const Matrix &B) const { return (Matrix(*this) += B); }
  Matrix operator-(const Matrix &B) const { return (Matrix(*this) -= B); }
  Matrix operator*(const Matrix &B) const { return (Matrix(*this) *= B); }
  Matrix operator^(const long long k) const { return (Matrix(*this) ^= k); }

  Matrix trans() {
    size_t m = height(), n = width();
    Matrix res(n, m);
    for (int i = 0; i < n; ++i)
      for (int j = 0; j < m; ++j) res[i][j] = (*this)[j][i];
    return res;
  }

  Matrix inv() {
    assert(height() == width());
    size_t n = height();
    Matrix B(n, 2 * n);
    for (int i = 0; i < n; ++i) {
      B[i][i + n] = 1;
      for (int j = 0; j < n; ++j) B[i][j] = (*this)[i][j];
    }
    for (int i = 0; i < n; ++i) {
      int piv = i;
      for (int j = i; j < n; ++j)
        if (abs(B[j][i]) > abs(B[piv][i])) piv = j;
      // not exist or unique
      assert(abs(B[piv][i]) >= 0);
      swap(B[i], B[piv]);
      for (int j = i + 1; j < 2 * n; ++j) B[i][j] /= B[i][i];
      for (int j = 0; j < n; ++j)
        if (i != j)
          for (int k = i + 1; k < 2 * n; ++k) B[j][k] -= B[j][i] * B[i][k];
    }
    Matrix res(n);
    for (int i = 0; i < n; ++i)
      for (int j = 0; j < n; ++j) res[i][j] = B[i][j + n];
    return res;
  }

  T det() {
    int m = height(), n = width();
    assert(m == n);
    T res = 1;
    Matrix B(m);
    for (int i = 0; i < m; ++i)
      for (int j = 0; j < n; ++j) B[i][j] = (*this)[i][j];
    for (int i = 0; i < n; ++i) {
      int piv = i;
      for (int j = i + 1; j < m; ++j)
        if (B[j][i] != 0) {
          piv = j;
          break;
        }
      // if (abs(B[j][i]) > abs(B[piv][i])) piv = j;
      if (B[piv][i] == 0) return (T)0;
      // if (abs(B[piv][i]) < EPS) return (T)0;  // B[piv][i] < EPS
      if (piv != i) swap(B[i], B[piv]), res = -res;
      res *= B[i][i];
      // for (int j = i + 1; j < m; ++j)
      //   for (int k = n - 1; k >= i; --k) B[j][k] -= B[i][k] * B[j][i] /
      //   B[i][i];
      {
        const T d = (T)1 / B[i][i];
        for (int j = i + 1; j < n; ++j) B[i][j] *= d;
        for (int j = i + 1; j < m; ++j)
          for (int k = i + 1; k < n; ++k) B[j][k] -= B[i][k] * B[j][i];
      }
    }
    return res;
  }

  T cofactor(int r = -1, int c = -1) {
    int m = height(), n = width();
    if (r < 0) r = c = m - 1;
    assert(m == n && m > 1 && r < m && c < n);
    Matrix mat(m - 1, n - 1);
    for (int i = 0, rcnt = 0; i < m; ++i)
      if (i != r) {
        int ccnt = 0;
        for (int j = 0; j < n; ++j)
          if (j != c) mat[rcnt][ccnt++] = (*this)[i][j];
        ++rcnt;
      }
    T res = mat.det();
    if ((r ^ c) & 1) res *= -1;
    return res;
  }

  friend ostream &operator<<(ostream &os, Matrix &p) {
    size_t m = p.height(), n = p.width();
    for (int i = 0; i < m; i++) {
      os << "[";
      for (int j = 0; j < n; j++) {
        os << p[i][j] << (j + 1 == n ? "]\n" : ",");
      }
    }
    return (os);
  }
};

template <int mod = (int)(1e9 + 7)>
struct ModInt {
  int x;
  constexpr ModInt() : x(0) {}
  constexpr ModInt(int64_t y)
      : x(y >= 0 ? y % mod : (mod - (-y) % mod) % mod) {}
  constexpr ModInt &operator+=(const ModInt &p) noexcept {
    if ((x += p.x) >= mod) x -= mod;
    return *this;
  }
  constexpr ModInt &operator-=(const ModInt &p) noexcept {
    if ((x += mod - p.x) >= mod) x -= mod;
    return *this;
  }
  constexpr ModInt &operator*=(const ModInt &p) noexcept {
    x = (int)(1LL * x * p.x % mod);
    return *this;
  }
  constexpr ModInt &operator/=(const ModInt &p) noexcept {
    *this *= p.inverse();
    return *this;
  }
  constexpr ModInt operator-() const { return ModInt(-x); }
  constexpr ModInt operator+(const ModInt &p) const noexcept {
    return ModInt(*this) += p;
  }
  constexpr ModInt operator-(const ModInt &p) const noexcept {
    return ModInt(*this) -= p;
  }
  constexpr ModInt operator*(const ModInt &p) const noexcept {
    return ModInt(*this) *= p;
  }
  constexpr ModInt operator/(const ModInt &p) const noexcept {
    return ModInt(*this) /= p;
  }
  constexpr bool operator==(const ModInt &p) const noexcept { return x == p.x; }
  constexpr bool operator!=(const ModInt &p) const noexcept { return x != p.x; }
  constexpr ModInt inverse() const noexcept {
    int a = x, b = mod, u = 1, v = 0, t = 0;
    while (b > 0) {
      t = a / b;
      swap(a -= t * b, b);
      swap(u -= t * v, v);
    }
    return ModInt(u);
  }
  constexpr ModInt pow(int64_t n) const {
    ModInt res(1), mul(x);
    while (n) {
      if (n & 1) res *= mul;
      mul *= mul;
      n >>= 1;
    }
    return res;
  }
  friend constexpr ostream &operator<<(ostream &os, const ModInt &p) noexcept {
    return os << p.x;
  }
  friend constexpr istream &operator>>(istream &is, ModInt &a) noexcept {
    int64_t t = 0;
    is >> t;
    a = ModInt<mod>(t);
    return (is);
  }
  constexpr int get_mod() { return mod; }
};
using mint = ModInt<>;

int n, k, c, t;

int main() {
  cin >> n >> k >> c >> t;
  Matrix<mint> mat(5 * n, 5 * n), st(5 * n, 1);
  st[c - 1][0] = 1;
  for (int i = 0; i < 4 * n; ++i) mat[i + n][i] = 1;
  for (int i = 0; i < k; ++i) {
    int a, b, p;
    cin >> a >> b >> p, --a, --p;
    p *= n;
    for (int j = 0; j < a; ++j) mat[j + b][j + p] += 1;
    for (int j = a; j < a + b; ++j) mat[j - a][j + p] += 1;
    for (int j = a + b; j < n; ++j) mat[j][j + p] += 1;
  }
  mat ^= t;
  mat *= st;
  cout << mat[0][0] << endl;
  return 0;
}
accuracy: 1
time_ms: 310
memory_kb: 3924
final_rank: 3

code_snippet: #line 1 "g.cpp"
#pragma region Macros
#include <bits/stdc++.h>
using namespace std;
template <class T> inline bool chmax(T &a, T b) {
    if(a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <class T> inline bool chmin(T &a, T b) {
    if(a > b) {
        a = b;
        return 1;
    }
    return 0;
}
#ifdef DEBUG
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
    os << '{';
    for(int i = 0; i < (int)v.size(); i++) {
        if(i) { os << ','; }
        os << v[i];
    }
    os << '}';
    return os;
}
void debugg() { cerr << endl; }
template <class T, class... Args>
void debugg(const T &x, const Args &... args) {
    cerr << " " << x;
    debugg(args...);
}
#define debug(...)                                                             \
    cerr << __LINE__ << " [" << #__VA_ARGS__ << "]: ", debugg(__VA_ARGS__)
#define dump(x) cerr << __LINE__ << " " << #x << " = " << (x) << endl
#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif

struct Setup {
    Setup() {
        cin.tie(0);
        ios::sync_with_stdio(false);
        cout << fixed << setprecision(15);
    }
} __Setup;

using ll = long long;
#define ALL(v) (v).begin(), (v).end()
#define RALL(v) (v).rbegin(), (v).rend()
#define FOR(i, a, b) for(int i = (a); i < int(b); i++)
#define REP(i, n) FOR(i, 0, n)
const int INF = 1 << 30;
const ll LLINF = 1LL << 60;
constexpr int MOD = 1000000007;
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};

void Case(int i) { cout << "Case #" << i << ": "; }
#pragma endregion Macros

#line 1 "/home/siro53/kyo-pro/compro_library/math/modint.hpp"
template <int mod> struct ModInt {
    int x;
    ModInt() : x(0) {}
    ModInt(int64_t y) : x(y >= 0 ? y % mod : (mod - (-y) % mod) % mod) {}
    ModInt &operator+=(const ModInt &p) {
        if((x += p.x) >= mod)
            x -= mod;
        return *this;
    }
    ModInt &operator-=(const ModInt &p) {
        if((x += mod - p.x) >= mod)
            x -= mod;
        return *this;
    }
    ModInt &operator*=(const ModInt &p) {
        x = (int)(1LL * x * p.x % mod);
        return *this;
    }
    ModInt &operator/=(const ModInt &p) {
        *this *= p.inv();
        return *this;
    }
    ModInt operator-() const { return ModInt(-x); }
    ModInt operator+(const ModInt &p) const { return ModInt(*this) += p; }
    ModInt operator-(const ModInt &p) const { return ModInt(*this) -= p; }
    ModInt operator*(const ModInt &p) const { return ModInt(*this) *= p; }
    ModInt operator/(const ModInt &p) const { return ModInt(*this) /= p; }
    bool operator==(const ModInt &p) const { return x == p.x; }
    bool operator!=(const ModInt &p) const { return x != p.x; }
    ModInt inv() const {
        int a = x, b = mod, u = 1, v = 0, t;
        while(b > 0) {
            t = a / b;
            swap(a -= t * b, b);
            swap(u -= t * v, v);
        }
        return ModInt(u);
    }
    ModInt pow(int64_t n) const {
        ModInt ret(1), mul(x);
        while(n > 0) {
            if(n & 1)
                ret *= mul;
            mul *= mul;
            n >>= 1;
        }
        return ret;
    }
    friend ostream &operator<<(ostream &os, const ModInt &p) {
        return os << p.x;
    }
    friend istream &operator>>(istream &is, ModInt &a) {
        int64_t t;
        is >> t;
        a = ModInt<mod>(t);
        return (is);
    }
    static int get_mod() { return mod; }
};
#line 70 "g.cpp"
using mint = ModInt<MOD>;
#line 1 "/home/siro53/kyo-pro/compro_library/math/matrix.hpp"
// 行列ライブラリ
template <class T> struct Matrix {
    vector<vector<T>> A;

    Matrix() {}

    Matrix(size_t n, size_t m) : A(n, vector<T>(m, 0)) {}

    Matrix(size_t n) : A(n, vector<T>(n, 0)){};

    size_t height() const { return (A.size()); }

    size_t width() const { return (A[0].size()); }

    inline const vector<T> &operator[](int k) const { return (A.at(k)); }

    inline vector<T> &operator[](int k) { return (A.at(k)); }

    // 単位行列
    static Matrix I(size_t n) {
        Matrix mat(n);
        for(int i = 0; i < n; i++)
            mat[i][i] = 1;
        return (mat);
    }

    Matrix &operator+=(const Matrix &B) {
        size_t n = height(), m = width();
        assert(n == B.height() && m == B.width());
        for(int i = 0; i < n; i++)
            for(int j = 0; j < m; j++)
                (*this)[i][j] += B[i][j];
        return (*this);
    }

    Matrix &operator-=(const Matrix &B) {
        size_t n = height(), m = width();
        assert(n == B.height() && m == B.width());
        for(int i = 0; i < n; i++)
            for(int j = 0; j < m; j++)
                (*this)[i][j] -= B[i][j];
        return (*this);
    }

    Matrix &operator*=(const Matrix &B) {
        size_t n = height(), m = B.width(), p = width();
        assert(p == B.height());
        vector<vector<T>> C(n, vector<T>(m, 0));
		T sum;
        for(int i = 0; i < n; i++){
            for(int j = 0; j < m; j++){
				sum = 0;
                for(int k = 0; k < p; k++){
                    sum += (*this)[i][k] * B[k][j];
				}
				C[i][j] = sum;
			}
		}
        A.swap(C);
        return (*this);
    }

    // 累乗
    Matrix &operator^=(long long k) {
        Matrix B = Matrix::I(height());
        while(k > 0) {
            if(k & 1)
                B *= *this;
            *this *= *this;
            k >>= 1LL;
        }
        A.swap(B.A);
        return (*this);
    }

    Matrix operator+(const Matrix &B) const { return (Matrix(*this) += B); }

    Matrix operator-(const Matrix &B) const { return (Matrix(*this) -= B); }

    Matrix operator*(const Matrix &B) const { return (Matrix(*this) *= B); }

    Matrix operator^(const long long k) const { return (Matrix(*this) ^= k); }

    friend ostream &operator<<(ostream &os, Matrix &p) {
        size_t n = p.height(), m = p.width();
        for(int i = 0; i < n; i++) {
            os << "[";
            for(int j = 0; j < m; j++) {
                os << p[i][j] << (j + 1 == m ? "]\n" : ",");
            }
        }
        return (os);
    }

    // 行列式
    T determinant() {
        Matrix B(*this);
        assert(width() == height());
        T ret = 1;
        for(int i = 0; i < width(); i++) {
            int idx = -1;
            for(int j = i; j < width(); j++) {
                if(B[j][i] != 0)
                    idx = j;
            }
            if(idx == -1)
                return (0);
            if(i != idx) {
                ret *= -1;
                swap(B[i], B[idx]);
            }
            ret *= B[i][i];
            T vv = B[i][i];
            for(int j = 0; j < width(); j++) {
                B[i][j] /= vv;
            }
            for(int j = i + 1; j < width(); j++) {
                T a = B[j][i];
                for(int k = 0; k < width(); k++) {
                    B[j][k] -= B[i][k] * a;
                }
            }
        }
        return (ret);
    }
};
#line 72 "g.cpp"
using matrix = Matrix<mint>;

int main() {
    int N, K, C, T;
    cin >> N >> K >> C >> T;
    vector<int> a(K), b(K), t(K);
    REP(i, K) {
        cin >> a[i] >> b[i] >> t[i];
        a[i]--; t[i]--;
    }

    matrix A(N*5, N*5);
    REP(i, 4*N) A[i+N][i] = 1;
    REP(from, N) {
        REP(i, K) {
            int to;
            if(a[i] <= from and from <= a[i] + b[i] - 1) {
                to = from - a[i];
            }
            else if(from < a[i]) {
                to = from + b[i];
            }
            else {
                to = from;
            }
            assert(0 <= from and from < N);
            assert(0 <= to and to < N);
            A[to][from + t[i] * N] += 1;
        }
    }
    A ^= T;

    matrix B(5*N, 1);
    B[C-1][0] = 1;
    A *= B;

    mint ans = A[0][0]; 

    cout << ans << endl;
}
accuracy: 1
time_ms: 310
memory_kb: 3884
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;
using uint = unsigned;
using ll = long long;

uint mod = 1000000007;
struct Modint{
    uint x = 0;
    Modint(const Modint& a): x(a.x){}
    Modint(ll a){
        a %= ll(mod);
        if(a < 0) a += mod;
        x = a;
    }
    Modint(){}
    Modint& operator+=(const Modint& a){
        x += a.x;
        if(x >= mod) x -= mod;
        return *this;
    }
    Modint& operator*=(const Modint& a){
        x = uint64_t(x) * a.x % mod;
        return *this;
    }
    Modint operator+(const Modint& a) const {
        return Modint(*this) += a;
    }
    Modint operator*(const Modint& a) const {
        return Modint(*this) *= a;
    }
    void operator++(int){
        *this += 1;
    }
};
struct Matrix{
    vector<vector<Modint>> x;
    Matrix(ll n): x(n, vector<Modint>(n)){}
    Matrix operator*(const Matrix& a) const {
        const ll n = size();
        Matrix ans(n);
        for(ll i = 0; i < n; i++) for(ll j = 0; j < n; j++) for(ll k = 0; k < n; k++) ans[i][k] += x[i][j] * a[j][k];
        return ans;
    }
    Matrix pow(ll x) const {
        const ll n = size();
        Matrix ans(n), a = *this;
        for(ll i = 0; i < n; i++) ans[i][i] = 1;
        while(x){
            if(x & 1) ans = ans * a;
            a = a * a;
            x >>= 1;
        }
        return ans;
    }
    vector<Modint>& operator[](ll i){ return x[i]; }
    const vector<Modint>& operator[](ll i) const { return x[i]; }
    ll size() const { return x.size(); }
};
int main(){
    ll n, k, c, t;
    cin >> n >> k >> c >> t;
    Matrix d(5 * n);
    for(ll i = n; i < 5 * n; i++) d[i][i - n] = 1;
    for(ll i = 0; i < k; i++){
        ll a, b, t;
        cin >> a >> b >> t;
        a--; t--;
        for(ll j = 0; j < a; j++) d[j][t * n + j + b]++;
        for(ll j = a; j < a + b; j++) d[j][t * n + j - a]++;
        for(ll j = a + b; j < n; j++) d[j][t * n + j]++;
    }
    c--;
    Matrix a(5 * n);
    a[0][c] = 1;
    a = a * d.pow(t);
    cout << a[0][0].x << endl;
}
accuracy: 1
time_ms: 1310
memory_kb: 4020
final_rank: 15

code_snippet: // #define _GLIBCXX_DEBUG // for STL debug (optional)
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <string>
#include <cstring>
#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <algorithm>
#include <map>
#include <set>
#include <complex>
#include <cmath>
#include <limits>
#include <cfloat>
#include <climits>
#include <ctime>
#include <cassert>
#include <numeric>
#include <fstream>
#include <functional>
#include <bitset>
using namespace std;
using ll = long long int;
using int64 = long long int;
 
template<typename T> void chmax(T &a, T b) {a = max(a, b);}
template<typename T> void chmin(T &a, T b) {a = min(a, b);}
template<typename T> void chadd(T &a, T b) {a = a + b;}
 
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
const int INF = 1LL << 29;
const ll LONGINF = 1LL << 60;
const ll MOD = 1000000007LL;

// ModInt begin

using ll = long long;
template<ll mod>
struct ModInt {
    ll v;
    ll mod_pow(ll x, ll n) const {
        return (!n) ? 1 : (mod_pow((x*x)%mod,n/2) * ((n&1)?x:1)) % mod;
    }
    ModInt(ll a = 0) : v((a %= mod) < 0 ? a + mod : a) {}
    ModInt operator+ ( const ModInt& b ) const {
        return (v + b.v >= mod ? ModInt(v + b.v - mod) : ModInt(v + b.v));
    }
    ModInt operator- () const {
        return ModInt(-v);
    }
    ModInt operator- ( const ModInt& b ) const {
        return (v - b.v < 0 ? ModInt(v - b.v + mod) : ModInt(v - b.v));
    }
    ModInt operator* ( const ModInt& b ) const {return (v * b.v) % mod;}
    ModInt operator/ ( const ModInt& b ) const {return (v * mod_pow(b.v, mod-2)) % mod;}
    
    bool operator== ( const ModInt &b ) const {return v == b.v;}
    bool operator!= ( const ModInt &b ) const {return !(*this == b); }
    ModInt& operator+= ( const ModInt &b ) {
        v += b.v;
        if(v >= mod) v -= mod;
        return *this;
    }
    ModInt& operator-= ( const ModInt &b ) {
        v -= b.v;
        if(v < 0) v += mod;
        return *this;
    }
    ModInt& operator*= ( const ModInt &b ) {
        (v *= b.v) %= mod;
        return *this;
    }
    ModInt& operator/= ( const ModInt &b ) {
        (v *= mod_pow(b.v, mod-2)) %= mod;
        return *this;
    }
    ModInt pow(ll x) { return ModInt(mod_pow(v, x)); }
    // operator int() const { return int(v); }
    // operator long long int() const { return v; }
};

template<ll mod>
ostream& operator<< (ostream& out, ModInt<mod> a) {return out << a.v;}
template<ll mod>
istream& operator>> (istream& in, ModInt<mod>& a) {
    in >> a.v;
    return in;
}

// ModInt end

// 行列ライブラリ

// size(): 行数を返す (列数は mat[0].size() で)
// 演算子: 複合代入 (+=, *=, -=), 単項 (-), 二項 (+, -, *, ==)
// eigen(N): N*N 単位行列を返す
// pow(mat, k): mat の k 乗を返す

template <typename T>
struct Matrix {
    vector< vector<T> > mat;
    Matrix() {}
    Matrix(int h, int w, T val = T(0)) : mat(h, vector<T>(w, val)) {}
    size_t size() const { return mat.size(); }
    const vector<T>& operator[](int i) const { return mat[i]; }
    vector<T>& operator[](int i) { return mat[i]; }

    Matrix<T> &operator+=(const Matrix<T>& rhs) {
        assert(mat.size() == rhs.size());
        assert(mat[0].size() == rhs[0].size());
        for(size_t i=0; i<mat.size(); i++) {
            for(size_t j=0; j<mat[0].size(); j++) {
                mat[i][j] += rhs[i][j];
            }
        }
        return *this;
    }

    Matrix<T> operator-() const {
        Matrix<T> res(*this);
        for(size_t i=0; i<res.size(); i++) {
            for(size_t j=0; j<res[0].size(); j++) {
                res[i][j] *= T(-1);
            }
        }
        return res;
    }

    Matrix<T>& operator-=(const Matrix<T>& rhs) {
        return (Matrix<T>(*this) += -rhs);
    }

    Matrix<T>& operator*=(const Matrix<T>& rhs) {
        assert(mat[0].size() == rhs.size());
        size_t H = mat.size(), W = rhs[0].size(), C = rhs.size();
        Matrix<T> res(H, W);
        for(size_t i=0; i<H; i++) {
            for(size_t j=0; j<W; j++) {
                for(size_t k=0; k<C; k++) {
                    res[i][j] += mat[i][k] * rhs[k][j];
                }
            }
        }
        this->mat = res.mat;
        return *this;
    }

    Matrix<T> operator+(const Matrix<T>& rhs) {
        return (Matrix<T>(*this) += rhs);
    }

    Matrix<T> operator*(const Matrix<T>& rhs) {
        return (Matrix<T>(*this) *= rhs);
    }

    Matrix<T> operator-(const Matrix<T> &rhs) {
        return (Matrix<T>(*this) -= rhs);
    }

    bool operator==(const Matrix<T> &rhs) const {
        return this->mat == rhs.mat;
    }
    bool operator!=(const Matrix<T> &rhs) const {
        return !(*this == rhs);
    }
};

template <typename T>
Matrix<T> eigen(size_t N) {
    Matrix<T> res(N, N, 0);
    for(size_t i=0; i<N; i++) res[i][i] = T(1);
    return res;
}

template <typename T>
Matrix<T> pow(Matrix<T> mat, long long int k) {
    Matrix<T> res = eigen<T>(mat.size());
    for(; k>0; k>>=1) {
        if(k & 1) res *= mat;
        mat *= mat;
    }
    return res;
}

template <typename T>
ostream& operator<< (ostream& out, Matrix<T> mat) {
    int H = mat.size(), W = mat[0].size();
    out << "[" << endl;
    for(int i=0; i<H; i++) {
        out << "  [ ";
        for(int j=0; j<W; j++) out << mat[i][j] << " ";
        out << "]" << endl;
    }
    out << "]" << endl;
    return out;
}

using mint = ModInt<MOD>;
int main() {
    int N, K, C, T; cin >> N >> K >> C >> T; C--;

    int M = 5 * N;
    Matrix<mint> mat(M, M);

    auto get_idx = [&](int time, int pos) {
        return time * N + pos;
    };

    for(int i=0; i<K; i++) {
        int a, b, t; cin >> a >> b >> t; a--;
        int l = a, r = a + b;
        vector<int> x, y;
        for(int j=0; j<N; j++) {
            if(l <= j and j < r) x.emplace_back(j);
            else y.emplace_back(j);
        }

        for(auto e : y) x.emplace_back(e);
        for(int j=0; j<N; j++) {
            int k = x[j]; // もともと k 番目だったものが j 番目に
            for(int s=0; s<1; s++) {
                int u = get_idx(s, j); // now
                int v = get_idx(s+t-1, k); // prev
                mat[u][v] += mint(1);
            }
        }
    }

    for(int i=0; i<N; i++) {
        for(int t=1; t<=4; t++) {
            int u = get_idx(t, i); // now
            int v = get_idx(t-1, i); // prev
            mat[u][v] += mint(1);
        }
    }

    mat = pow(mat, T);
    Matrix<mint> vec(M, 1);
    vec[C][0] = mint(1);

    vec = mat * vec;
    cout << vec[0][0] << endl;
    return 0;
}
accuracy: 1
time_ms: 1270
memory_kb: 4212
final_rank: 14

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


typedef vector<ll> V;
typedef vector<V> MATRIX;

int SIZE;
int base[40],work[40],next_loc[40];

MATRIX calc(MATRIX left,MATRIX right){

	MATRIX ret(SIZE,V(SIZE));

	for(int i = 0; i < SIZE; i++){
		for(int k = 0; k < SIZE; k++)ret[i][k] = 0;
	}

	for(int row = 0; row < SIZE; row++){
		for(int col = 0; col < SIZE; col++){
			for(int a = 0; a < SIZE; a++){
				ret[row][col] += left[row][a]*right[a][col]%MOD;
				ret[row][col] %= MOD;
			}
		}
	}

	return ret;
}


MATRIX pow(MATRIX MULT,int count){

	MATRIX ret(SIZE,V(SIZE));

	for(int row = 0; row < SIZE; row++){
		for(int col = 0; col < SIZE; col++){
			if(row == col)ret[row][col] = 1;
			else{
				ret[row][col] = 0;
			}
		}
	}

	while(count > 0){
		if(count%2 == 1)ret = calc(ret,MULT);
		MULT = calc(MULT,MULT);
		count /= 2;
	}

	return ret;
}


int main(){

	int N,K,C,T;
	scanf("%d %d %d %d",&N,&K,&C,&T);
	C--;

	for(int i = 0; i < N; i++)base[i] = i;

	SIZE = 5*N;

	MATRIX MULT(SIZE,V(SIZE));
	for(int row = 0; row < SIZE; row++){
		for(int col = 0; col < SIZE; col++)MULT[row][col] = 0;
	}

	int from,num,add_time;
	int work_index,base_row = 0,base_col;

	for(int loop = 0; loop < K; loop++){
		scanf("%d %d %d",&from,&num,&add_time);
		from--;

		work_index = 0;
		for(int i = 0;i < num; i++){
			work[work_index++] = base[from+i];
		}

		for(int i = 0; i < N; i++){
			if(i >= from && i <= from+num-1)continue;
			work[work_index++] = base[i];
		}

		base_col = N*(add_time-1);
		for(int i = 0; i < N; i++){
			MULT[base_row+work[i]][base_col+i]++;
		}
	}

	for(base_row = N; base_row <= 4*N; base_row += N){
		for(base_col = 0; base_col <= 4*N; base_col += N){
			if(base_row-N != base_col)continue;
			for(int i = 0; i < N; i++)MULT[base_row+i][base_col+i] = 1;
		}
	}

	MULT = pow(MULT,T);

	printf("%lld\n",MULT[C][0]%MOD);

	return 0;
}
accuracy: 1
time_ms: 760
memory_kb: 4876
final_rank: 13

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define GET_MACRO(_1, _2, _3, NAME, ...) NAME
#define _repl(i,a,b) for(int i=(int)(a);i<(int)(b);i++)
#define _rep(i,n) _repl(i,0,n)
#define rep(...) GET_MACRO(__VA_ARGS__, _repl, _rep)(__VA_ARGS__)
#define mp(a,b) make_pair((a),(b))
#define pb(a) push_back((a))
#define all(x) (x).begin(),(x).end()
#define uniq(x) sort(all(x)),(x).erase(unique(all(x)),end(x))
#define fi first
#define se second
#define dbg(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
void _dbg(string){cout<<endl;}
template<class H,class... T> void _dbg(string s,H h,T... t){int l=s.find(',');cout<<s.substr(0,l)<<" = "<<h<<", ";_dbg(s.substr(l+1),t...);}
template<class T,class U> ostream& operator<<(ostream &o, const pair<T,U> &p){o<<"("<<p.fi<<","<<p.se<<")";return o;}
template<class T> ostream& operator<<(ostream &o, const vector<T> &v){o<<"[";for(T t:v){o<<t<<",";}o<<"]";return o;}

#define MOD 1000000007

typedef vector<vector<long>> mat;

// return A*B
mat mat_mul(const mat &A, const mat &B){
  int n=A.size(), m=B[0].size(), l=B.size();
  mat ret(n, vector<long>(m, 0));
  rep(i,n) rep(k,l) if(A[i][k]!=0) rep(j,m){
    (ret[i][j] += A[i][k] * B[k][j]) %= MOD;
  }
  return ret;
}

// A^p
mat mat_pow(const mat &A, long p){
  int n = A.size();
  mat tmp(A), ret(n, vector<long>(n,0));
  rep(i,n) ret[i][i] = 1;
  while(p>0){
    if(p&1) ret = mat_mul(tmp, ret);
    tmp = mat_mul(tmp, tmp);
    p /= 2;
  }
  return ret;
}

int main(){
  int n,k,c,T;
  cin>>n>>k>>c>>T;
  c--;

  vector<int> a(k), b(k), t(k);
  rep(i,k) cin>>a[i]>>b[i]>>t[i];
  rep(i,k) a[i]--;

  int sz = 5*n;

  mat A(sz, vector<long>(sz, 0));
  rep(i,n,sz){
    A[i-n][i] += 1;
  }

  rep(i,k){
    rep(j,n){
      int to = (t[i]-1)*n + j;
      if(j < a[i]) to += b[i];
      else if(j < a[i]+b[i]) to -= a[i];
      A[to][j] += 1;
    }
  }

  A = mat_pow(A, T);

  cout << A[0][c] << endl;

  return 0;
}
accuracy: 1
time_ms: 300
memory_kb: 4196
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i))
#define all(x) (x).begin(),(x).end()
#define pb push_back
#define fi first
#define se second
#define dbg(x) cout<<#x" = "<<((x))<<endl
template<class T,class U> ostream& operator<<(ostream& o, const pair<T,U> &p){o<<"("<<p.fi<<","<<p.se<<")";return o;}
template<class T> ostream& operator<<(ostream& o, const vector<T> &v){o<<"[";for(T t:v){o<<t<<",";}o<<"]";return o;}

using vl = vector<ll>;
using mat = vector<vl>;

const ll mod = 1e9+7;

mat mul(const mat &a, const mat &b)
{
    int n = a.size();
    mat c(n,vl(n));
    rep(i,n)rep(j,n)rep(k,n) (c[i][j]+=a[i][k]*b[k][j])%=mod;
    return c;
}

vl mul(const mat &a, const vl &b)
{
    int n = a.size();
    vl c(n);
    rep(i,n)rep(j,n) (c[i]+=a[i][j]*b[j])%=mod;
    return c;
}

mat mat_pow(const mat &a, int T)
{
    int n = a.size();
    mat ret(n,vl(n));
    rep(i,n) ret[i][i] = 1;

    mat p(a);
    while(T)
    {
        if(T&1) ret = mul(ret,p);
        p = mul(p,p);
        T>>=1;
    }
    return ret;
}

int main()
{
    int n,k,C,T;
    cin >>n >>k >>C >>T;
    --C;

    vector<int> a(k),b(k),t(k);
    rep(i,k)
    {
        cin >>a[i] >>b[i] >>t[i];
        --a[i];
    }

    int SZ = 5*n;

    mat A(SZ,vl(SZ));
    // make A
    for(int i=n; i<5*n; ++i) A[i-n][i] += 1;
    rep(i,k)
    {
        rep(j,n)
        {
            int idx = (t[i]-1)*n+j;
            if(j<a[i]) idx += b[i];
            else if(j<a[i]+b[i]) idx -= a[i];

            A[idx][j] += 1;
        }
    }

    vl B(SZ);
    B[C] = 1;

    vl res = mul(mat_pow(A,T),B);
    cout << res[0] << endl;
    return 0;
}
accuracy: 1
time_ms: 650
memory_kb: 4180
final_rank: 8

code_snippet: #include "bits/stdc++.h"
using namespace std;


const int mod = 1000000007;
struct Mod {
public:
	int num;
	Mod() : Mod(0) { ; }
	Mod(long long int n) : num((n % mod + mod) % mod) {
		static_assert(mod<INT_MAX / 2, "mod is too big, please make num 'long long int' from 'int'");
	}
	Mod(int n) : Mod(static_cast<long long int>(n)) { ; }
	operator int() { return num; }
};

Mod operator+(const Mod a, const Mod b) { return Mod((a.num + b.num) % mod); }
Mod operator+(const long long int a, const Mod b) { return Mod(a) + b; }
Mod operator+(const Mod a, const long long int  b) { return b + a; }
Mod operator++(Mod &a) { return a + Mod(1); }
Mod operator-(const Mod a, const Mod b) { return Mod((mod + a.num - b.num) % mod); }
Mod operator-(const long long int a, const Mod b) { return Mod(a) - b; }
Mod operator--(Mod &a) { return a - Mod(1); }
Mod operator*(const Mod a, const Mod b) { return Mod(((long long)a.num * b.num) % mod); }
Mod operator*(const long long int a, const Mod b) { return Mod(a)*b; }
Mod operator*(const Mod a, const long long int b) { return Mod(b)*a; }
Mod operator*(const Mod a, const int b) { return Mod(b)*a; }
Mod operator+=(Mod &a, const Mod b) { return a = a + b; }
Mod operator+=(long long int &a, const Mod b) { return a = a + b; }
Mod operator-=(Mod &a, const Mod b) { return a = a - b; }
Mod operator-=(long long int &a, const Mod b) { return a = a - b; }
Mod operator*=(Mod &a, const Mod b) { return a = a * b; }
Mod operator*=(long long int &a, const Mod b) { return a = a * b; }
Mod operator*=(Mod& a, const long long int &b) { return a = a * b; }
Mod operator^(const Mod a, const int n) {
	if (n == 0) return Mod(1);
	Mod res = (a * a) ^ (n / 2);
	if (n % 2) res = res * a;
	return res;
}
Mod mod_pow(const Mod a, const long long  int n) {
	if (n == 0) return Mod(1);
	Mod res = mod_pow((a * a), (n / 2));
	if (n % 2) res = res * a;
	return res;
}
Mod inv(const Mod a) { return a ^ (mod - 2); }
Mod operator/(const Mod a, const Mod b) {
	assert(b.num != 0);
	return a * inv(b);
}
Mod operator/(const long long int a, const Mod b) {
	return Mod(a) / b;
}
Mod operator/=(Mod &a, const Mod b) {
	return a = a / b;
}

#define MAX_MOD_N 1024000

Mod fact[MAX_MOD_N], factinv[MAX_MOD_N];
void init(const int amax = MAX_MOD_N) {
	fact[0] = Mod(1); factinv[0] = 1;
	for (int i = 0; i < amax - 1; ++i) {
		fact[i + 1] = fact[i] * Mod(i + 1);
		factinv[i + 1] = factinv[i] / Mod(i + 1);
	}
}
Mod comb(const int a, const int b) {
	return fact[a] * factinv[b] * factinv[a - b];
}


template<typename T>
vector<vector<T>> keisann(const vector<vector<T>>l, const vector<vector<T>>r) {
	vector<vector<T>>ans(l.size(), vector<T>(r[0].size()));
	assert(l[0].size() == r.size());
	for (unsigned int h = 0; h < l.size(); ++h) {
		for (unsigned int i = 0; i < r.size(); ++i) {
			for (unsigned int w = 0; w < r[0].size(); ++w) {

				ans[h][w] += l[h][i] * r[i][w];
			}
		}
	}
	return ans;
}

template<typename T>
vector<vector<T>>powgyou(vector<vector<T>>a, const long long int n) {
	assert(a.size() == a[0].size());
	if (!n) {
		vector<vector<T>>e(a.size(), vector<T>(a[0].size()));
		for (unsigned int i = 0; i < a.size(); ++i) {
			e[i][i] = 1;
		}
		return e;
	}
	if (n == 1)return a;
	else {
		vector<vector<T>>ans(a.size(), vector<T>(a[0].size(), 0));
		ans = powgyou(a, n / 2);
		ans = keisann(ans, ans);
		if (n % 2) {
			ans = keisann(ans, a);
		}
		return ans;
	}
}

int main(){
	int N, K, C, T; cin >> N >> K >> C >> T;
	
	C--;
	vector<vector<Mod>>from(5*N, vector<Mod>(1));
	from[5*C][0]+=1;
	vector<vector<Mod>>gyou(5*N, vector<Mod>(5*N));
	for (int i = 0; i < N; ++i) {
		for (int j = 0; j < 4; ++j) {
			gyou[5 * i + j][5 *i + j + 1] = 1;
		}
	}
	for (int i = 0; i < K; ++i) {
		int a, b, t; cin >> a >> b >> t;
		a--;

		for (int j = 0; j < N; ++j) {
			const int afrom = 5 * j;
			int to;
			if (j<a) {
				to = 5 * (j + b) + t - 1;
			}
			else if ((j>a + b - 1)) {
				to = afrom+t-1;
			}
			else {
				to = 5 * (j - a) + t-1;

			}
			gyou[to][afrom] += 1;
		}
	}
	auto kake = powgyou(gyou,T);
	auto ans = keisann(kake, from);
	cout << ans[0][0] << endl;
	return 0;
}
accuracy: 1
time_ms: 1170
memory_kb: 17820
final_rank: 20

code_snippet: #include<iostream>
#include<vector>

#define rep(i,n) for(int i=0;i<(int)n;i++)
using namespace std;
typedef long long ll;
typedef vector<ll> vec;
typedef vector<vec> mat;
const ll mod = 1000000007;
const int tMAX = 5;

inline void init(mat &A, int n, int m){
  A = mat(n,vec(m,0));
}

inline mat add(mat A, mat B){
  mat res = A;
  rep(i,A.size())rep(j,A[i].size())(res[i][j] += B[i][j]) %= mod;
  return res;
}

inline mat mul(mat A, mat B){
  mat res; init(res,A.size(),B[0].size());
  rep(i,A.size())rep(j,B[0].size()){
    rep(k,B.size())res[i][j] += (A[i][k] * B[k][j]) % mod;
    res[i][j] %= mod;
  }
  return res;
}

inline mat pow_mat(mat &A, ll n){
  if(n==1LL)return A;
  mat B = pow_mat(A,n/2), res = mul(B,B);
  if(n&1)res = mul(A,res);
  return res;
}

ll N,K,C,T,tr;
ll a, b, t;
vec shuffle(50), perm(50);
mat perm_mat[10], dp[500100], tmp;
mat large_mat, thin_mat;

int main(){
  cin >> N >> K >> C >> T;

  rep(i,tMAX+1)init(perm_mat[i],N,N);
  rep(i,N)perm[i] = i;

  rep(i,K){
    cin >> a >> b >> t;
    rep(j,b)shuffle[j] = perm[j+a-1];
    rep(j,a-1)shuffle[b+j] = perm[j];
    for(int j=a+b-1;j<N;j++)shuffle[j] = perm[j];
    rep(j,N)perm_mat[t][j][shuffle[j]]++;
  }

  rep(i,tMAX+1)init(dp[i],N,N);
  rep(i,N)dp[0][i][i] = 1;
 
  rep(i,tMAX)rep(j,tMAX){
    if(i+j+1<=tMAX){
      tmp = mul(perm_mat[j+1],dp[i]);
      dp[i+j+1] = add(dp[i+j+1],tmp);
    }
  }

  init(large_mat,N*tMAX,N*tMAX);
  rep(id,tMAX){
    rep(i,N)rep(j,N)large_mat[i][j+id*N] = perm_mat[id+1][i][j];
  }
  rep(i,N*(tMAX-1))large_mat[i+N][i] = 1;

  init(thin_mat,N*tMAX,N);
  rep(id,tMAX){
    rep(i,N)rep(j,N)thin_mat[i+id*N][j] = dp[tMAX-1-id][i][j];
  }

  tmp = pow_mat(large_mat,T);
  cout << mul(tmp,thin_mat)[(tMAX-1)*N][C-1] << endl;
}
accuracy: 1
time_ms: 470
memory_kb: 16880
final_rank: 19

code_snippet: #include <valarray>
#include <vector>
#include <cstdio>
using namespace std;
typedef valarray<__int128_t>V;
int n,m=1000000007;
V z;
V &Me(const V &_x,const V &_y){
	int i=0,j;
	for(;i<n;i++)for(j=0;j<n;j++)z[i*n+j]=(_x[slice(i*n,n,1)]*_y[slice(j,n,n)]).sum()%m;
	return z;
}
V &Mx(const V &_x){
	int i=0,j;
	for(;i<n;i++)for(j=0;j<n;j++)z[i*n+j]=(_x[slice(i*n,n,1)]*_x[slice(j,n,n)]).sum()%m;
	return z;
}
int main(){
	int N,K,C,T;
	scanf("%d%d%d%d",&N,&K,&C,&T);C--;
	vector<int>a(K),b(K),t(K);
	for(int i=0;i<K;i++)scanf("%d%d%d",&a[i],&b[i],&t[i]),a[i]--;
	n=N*5;
	V x(n*n);
	V e(n*n);
	z.resize(n*n);
	for(int i=0;i<n;i++)e[i*n+i]=1;
	for(int i=0;i<K;i++)for(int j=0;j<N;j++){
		int nj=j<a[i]?j+b[i]:j<a[i]+b[i]?j-a[i]:j;
		x[j*5*n+nj*5+t[i]-1]++;
	}
	for(int i=0;i<N;i++)for(int j=1;j<5;j++)x[(i*5+j)*n+i*5+j-1]++;
	for(;T;T>>=1){
		if(T&1)e=Me(e,x);
		x=Mx(x);
	}
	printf("%lld\n",(long long)e[C*5*n]);
}
accuracy: 1
time_ms: 420
memory_kb: 4236
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define int long long   // <-----!!!!!!!!!!!!!!!!!!!
 
#define rep(i,n) for (int i=0;i<(n);++i)
#define rep2(i,a,b) for (int i=(a);i<(b);++i)
#define rrep(i,n) for (int i=(n)-1;i>=0;--i)
#define rrep2(i,a,b) for (int i=(a)-1;i>=b;--i)
#define chmin(a,b) (a)=min((a),(b));
#define chmax(a,b) (a)=max((a),(b));
#define all(a) (a).begin(),(a).end()
#define rall(a) (a).rbegin(),(a).rend()
#define printV(_v) cout<<(#_v)<<":";for(auto(_x):(_v)){cout<<" "<<(_x);}cout<<endl;
#define printVS(vs) cout<<(#vs)<<":"<<endl;for(auto(s):(vs)){cout<<(s)<< endl;}
#define printVV(vv) cout<<(#vv)<<":"<<endl;for(auto(v):(vv)){for(auto(x):(v)){cout<<" "<<(x);}cout<<endl;}
#define printP(p) cout<<(#p)<<(p).first<<" "<<(p).second<<endl;
#define printVP(vp) cout<<(#vp)<<":"<<endl;for(auto(p):(vp)){cout<<(p).first<<" "<<(p).second<<endl;}
 
inline void output(){ cout << endl; }
template<typename First, typename... Rest>
inline void output(const First& first, const Rest&... rest) {
    cout << first << " "; output(rest...);
}
 
using ll = long long;
using Pii = pair<int, int>;
using TUPLE = tuple<int, int, int>;
using vi = vector<int>;
using vvi = vector<vi>;
using vvvi = vector<vvi>;
const int inf = 1ll << 60;
const int mod = 1e9 + 7;
using Graph = vector<vector<int>>;
 
using Vec = vector<int>;
using Mat = vector<Vec>;
 
Mat mulMatMat(const Mat& a, const Mat& b) {
    int n = a.size();
    int m = b[0].size();
    assert(a[0].size() == b.size());
    Mat c(n, Vec(m, 0));
    rep(i, n) {
        rep(j, m) {
            rep(k, a[0].size()) {
                (c[i][j] += a[i][k] * b[k][j]) %= mod;
            }
        }
    }
    return c;
}
 
void addMatMat(Mat& a, const Mat& b) {
    assert(a.size() == b.size());
    assert(a[0].size() == b[0].size());
    rep(i, a.size()) {
        rep(j, a[0].size()) {
            (a[i][j] += b[i][j]) %= mod;
        }
    }
}
 
Vec mulMatVec(const Mat& a, const Vec& v) {
    int n = a.size();
    assert(a[0].size() == v.size());
    Vec c(n, 0);
    rep(i, n) {
        rep(j, a[0].size()) {
            (c[i] += a[i][j] * v[j]) %= mod;
        }
    }
    return c;
}
 
Mat identityMatrix(int n) {
    Mat a(n, Vec(n));
    rep(i, n) a[i][i] = 1;
    return a;
}
 
Mat powMat(Mat a, int t) {
    assert(a.size() == a[0].size());
    Mat b = identityMatrix(a.size());
    for (; t > 0; t >>= 1) {
        if (t & 1) {
            b = mulMatMat(a, b);
        }
        a = mulMatMat(a, a);
    }
    return b;
}
 
main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
 
    int N, K, C, T;
    cin >> N >> K >> C >> T;
    C--;
    vector<Mat> A(5, Mat(N, Vec(N)));
    rep(k, K) {
        int a, b, t;
        cin >> a >> b >> t;
        a--; t--;
        rep(i, a) A[t][i][i + b]++;
        rep2(i, a, a + b) A[t][i][i - a]++;
        rep2(i, a + b, N) A[t][i][i]++;
    }
 
    // rep(t, 5) {
    //     printVV(A[t]);
    // }
 
    Mat B(5*N, Vec(5*N));
    rep(t, 5) {
        rep(i, N) {
            rep(j, N) {
                B[i][j + t*N] = A[t][i][j];
            }
        }
    }
    rep(j, 4 * N) {
        B[j + N][j] = 1;
    }
 
    // printVV(B);
 
    vector<Mat> dp(5, Mat(N, Vec(N)));
    dp[0] = identityMatrix(N);
    rep2(i, 1, 5) {
        rep(j, i) {
            addMatMat(dp[i], mulMatMat(A[i - j - 1], dp[j]));
        }
    }
 
    // rep(t, 5) {
    //     printVV(dp[t]);
    // }
 
    auto D = powMat(B, T);
 
    Mat E(N, Vec(N));
    rep(k, 5) {
        Mat F(N, Vec(N));
        rep(i, N) {
            rep(j, N) {
                F[i][j] = D[i + 4*N][j + k*N];
            }
        }
        addMatMat(E, mulMatMat(F, dp[4 - k]));
    }
 
    cout << E[C][0] << endl;
}
accuracy: 1
time_ms: 660
memory_kb: 4212
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define int long long   // <-----!!!!!!!!!!!!!!!!!!!

#define rep(i,n) for (int i=0;i<(n);++i)
#define rep2(i,a,b) for (int i=(a);i<(b);++i)
#define rrep(i,n) for (int i=(n)-1;i>=0;--i)
#define rrep2(i,a,b) for (int i=(a)-1;i>=b;--i)
#define chmin(a,b) (a)=min((a),(b));
#define chmax(a,b) (a)=max((a),(b));
#define all(a) (a).begin(),(a).end()
#define rall(a) (a).rbegin(),(a).rend()
#define printV(_v) cout<<(#_v)<<":";for(auto(_x):(_v)){cout<<" "<<(_x);}cout<<endl;
#define printVS(vs) cout<<(#vs)<<":"<<endl;for(auto(s):(vs)){cout<<(s)<< endl;}
#define printVV(vv) cout<<(#vv)<<":"<<endl;for(auto(v):(vv)){for(auto(x):(v)){cout<<" "<<(x);}cout<<endl;}
#define printP(p) cout<<(#p)<<(p).first<<" "<<(p).second<<endl;
#define printVP(vp) cout<<(#vp)<<":"<<endl;for(auto(p):(vp)){cout<<(p).first<<" "<<(p).second<<endl;}

inline void output(){ cout << endl; }
template<typename First, typename... Rest>
inline void output(const First& first, const Rest&... rest) {
    cout << first << " "; output(rest...);
}

using ll = long long;
using Pii = pair<int, int>;
using TUPLE = tuple<int, int, int>;
using vi = vector<int>;
using vvi = vector<vi>;
using vvvi = vector<vvi>;
const int inf = 1ll << 60;
const int mod = 1e9 + 7;
using Graph = vector<vector<int>>;

using Vec = vector<int>;
using Mat = vector<Vec>;

Mat mulMatMat(const Mat& a, const Mat& b) {
    int n = a.size();
    int m = b[0].size();
    assert(a[0].size() == b.size());
    Mat c(n, Vec(m, 0));
    rep(i, n) {
        rep(j, m) {
            rep(k, a[0].size()) {
                (c[i][j] += a[i][k] * b[k][j]) %= mod;
            }
        }
    }
    return c;
}

void addMatMat(Mat& a, const Mat& b) {
    assert(a.size() == b.size());
    assert(a[0].size() == b[0].size());
    rep(i, a.size()) {
        rep(j, a[0].size()) {
            (a[i][j] += b[i][j]) %= mod;
        }
    }
}

Vec mulMatVec(const Mat& a, const Vec& v) {
    int n = a.size();
    assert(a[0].size() == v.size());
    Vec c(n, 0);
    rep(i, n) {
        rep(j, a[0].size()) {
            (c[i] += a[i][j] * v[j]) %= mod;
        }
    }
    return c;
}

Mat identityMatrix(int n) {
    Mat a(n, Vec(n));
    rep(i, n) a[i][i] = 1;
    return a;
}

Mat powMat(Mat a, int t) {
    assert(a.size() == a[0].size());
    Mat b = identityMatrix(a.size());
    for (; t > 0; t >>= 1) {
        if (t & 1) {
            b = mulMatMat(a, b);
        }
        a = mulMatMat(a, a);
    }
    return b;
}

main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);

    int N, K, C, T;
    cin >> N >> K >> C >> T;
    C--;
    vector<Mat> A(5, Mat(N, Vec(N)));
    rep(k, K) {
        int a, b, t;
        cin >> a >> b >> t;
        a--; t--;
        rep(i, a) A[t][i][i + b]++;
        rep2(i, a, a + b) A[t][i][i - a]++;
        rep2(i, a + b, N) A[t][i][i]++;
    }

    // rep(t, 5) {
    //     printVV(A[t]);
    // }

    Mat B(5*N, Vec(5*N));
    rep(t, 5) {
        rep(i, N) {
            rep(j, N) {
                B[i][j + t*N] = A[t][i][j];
            }
        }
    }
    rep(j, 4 * N) {
        B[j + N][j] = 1;
    }

    // printVV(B);

    vector<Mat> dp(5, Mat(N, Vec(N)));
    dp[0] = identityMatrix(N);
    rep2(i, 1, 5) {
        rep(j, i) {
            addMatMat(dp[i], mulMatMat(A[i - j - 1], dp[j]));
        }
    }

    // rep(t, 5) {
    //     printVV(dp[t]);
    // }

    auto D = powMat(B, T);

    Mat E(N, Vec(N));
    rep(k, 5) {
        Mat F(N, Vec(N));
        rep(i, N) {
            rep(j, N) {
                F[i][j] = D[i + 4*N][j + k*N];
            }
        }
        addMatMat(E, mulMatMat(F, dp[4 - k]));
    }

    cout << E[C][0] << endl;
}
accuracy: 1
time_ms: 690
memory_kb: 4264
final_rank: 11

code_snippet: #include<bits/stdc++.h>
using namespace std;
 
#define int long long
typedef pair<int,int>pint;
typedef vector<int>vint;
typedef vector<pint>vpint;
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define all(v) (v).begin(),(v).end()
#define rep(i,n) for(int i=0;i<(n);i++)
#define reps(i,f,n) for(int i=(f);i<(n);i++)
#define each(it,v) for(__typeof((v).begin()) it=(v).begin();it!=(v).end();it++)
template<class T,class U>inline void chmin(T &t,U f){if(t>f)t=f;}
template<class T,class U>inline void chmax(T &t,U f){if(t<f)t=f;}
 
typedef vector<vint>mat;
const int mod=1000000007;
 
mat mul(mat A,mat B){
     mat C(A.size(),vint(B[0].size()));
     rep(i,C.size()){
        rep(j,C[0].size()){
            rep(k,A[0].size()){
                (C[i][j]+=A[i][k]*B[k][j])%=mod;
            }
        }
     }
     return C;
}
 
mat mpow(mat A,int m){
    mat B(A.size(),vint(A.size()));
    rep(i,A.size())B[i][i]=1;
    for(;m;m>>=1,A=mul(A,A))if(m&1)B=mul(A,B);
    return B;
}
 
int N,K,C,T;
int a[114514],b[114514],t[114514];
signed main(){
    cin>>N>>K>>C>>T;C--;
    rep(i,K)cin>>a[i]>>b[i]>>t[i],a[i]--;
 
    mat X(N*5,vint(1)),A(N*5,vint(N*5));
    X[C][0]=1;
    rep(i,N*4)A[N+i][i]=1;
    rep(k,K){
        int bb=(t[k]-1)*N;
        rep(i,N){
            if(i<a[k])A[i+b[k]][bb+i]++;
            else if(i<a[k]+b[k])A[i-a[k]][bb+i]++;
            else A[i][bb+i]++;
        }
    }
 
 
    X=mul(mpow(A,T),X);
    cout<<X[0][0]<<endl;
    return 0;
}
accuracy: 1
time_ms: 650
memory_kb: 4780
final_rank: 12

code_snippet: #include<bits/stdc++.h>

#define rep(i,n) for(int i=0;i<(int)n;i++)
#define all(c) (c).begin(),(c).end()
#define mp make_pair
#define pb push_back
#define each(i,c) for(__typeof((c).begin()) i=(c).begin();i!=(c).end();i++)
#define dbg(x) cerr<<__LINE__<<": "<<#x<<" = "<<(x)<<endl

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int> pi;
const int inf = (int)1e9;
const double INF = 1e12, EPS = 1e-9;

const int mod = 1e9 + 7;
typedef vector<vi> M;
inline M operator*(const M & a, const M &b){
	M c(a.size(), vi(b[0].size()));
	rep(i, c.size()) rep(j, c[0].size()){
		ll s = 0;
		rep(k, a[0].size()) s += (ll)a[i][k] * b[k][j] % mod;
		c[i][j] = s % mod;
	}
	return c;
}
inline M pow(M a, ll m){
	M res(a.size(), vi(a.size()));
	rep(i, a.size()) res[i][i] = 1;
	for(; m; m /= 2){
		if(m & 1) res = res * a;
		a = a * a;
	}
	return res;
}

int n, K, c, T, a[1000], b[1000], t[1000];
int dp[10][40];


int main(){
	cin >> n >> K >> c >> T;
	rep(i, K) cin >> a[i] >> b[i] >> t[i], a[i]--;
	
	M A(5 * n, vi(5 * n));
	
	rep(s, 5 * n){
		memset(dp, 0, sizeof(dp));
		dp[s / n][s % n] = 1;
		rep(i, 5) rep(j, n) if(dp[i][j]) rep(k, K){
			int nj = j >= a[k] + b[k] ? j : j >= a[k] ? j - a[k] : j + b[k];
			(dp[i + t[k]][nj] += dp[i][j]) %= mod;
		}
		for(int i = 5; i < 10; i++) rep(j, n) (A[(i - 5) * n + j][s] += dp[i][j]) %= mod;
	}
	A = pow(A, T / 5);
	M x(5 * n, vi(1));
	x[c - 1][0] = 1;
	x = A * x;
	
	memset(dp, 0, sizeof(dp));
	rep(i, 5 * n) dp[i / n][i % n] = x[i][0];
	rep(i, 5) rep(j, n) if(dp[i][j]) rep(k, K){
		int nj = j >= a[k] + b[k] ? j : j >= a[k] ? j - a[k] : j + b[k];
		(dp[i + t[k]][nj] += dp[i][j]) %= mod;
	}
	cout << dp[T % 5][0] << endl;
	return 0;
}
accuracy: 1
time_ms: 310
memory_kb: 3688
final_rank: 1

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

typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef long long LL;
typedef pair<LL, LL> PLL;

#define ALL(a)  (a).begin(),(a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define EB emplace_back
#define MP make_pair
#define SZ(a) int((a).size())
#define EACH(i,c) for(typeof((c).begin()) i=(c).begin(); i!=(c).end(); ++i)
#define EXIST(s,e) ((s).find(e)!=(s).end())
#define SORT(c) sort((c).begin(),(c).end())

#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n)  FOR(i,0,n)

#define FF first
#define SS second
template<class S, class T>
istream& operator>>(istream& is, pair<S,T>& p){
  return is >> p.FF >> p.SS;
}

const double EPS = 1e-10;
const double PI  = acos(-1.0);
const LL MOD = 1e9+7;

typedef vector<LL> Col;
typedef vector<Col> Matrix;
Matrix mul(const Matrix& A, const Matrix& B){
  const int R = A.size(), C = B[0].size(), sz = B.size();
  Matrix AB(R, Col(C));

  for(int i=0;i<R;++i)
    for(int j=0;j<C;++j)
      for(int k=0;k<sz;++k)
		(AB[i][j] += A[i][k] * B[k][j]) %= MOD;

  return AB;
}

// O(N^3 lgN)
Matrix powA(const Matrix& A, int n){
  const int N = A.size();
  Matrix p(N, Col(N, 0)), w = A;
  for(int i=0;i<N;++i) p[i][i] = 1;

  while(n>0){
	if(n&1)
	  p = mul(p, w);
	w = mul(w, w);
	n >>= 1;
  }

  return p;
}

void dump(const Matrix& A){
  REP(i,SZ(A)){
	REP(j,SZ(A[i]))
	  cout << A[i][j] << (j%5==4?" | ":" ");
	cout << endl;
	if(i%5==4)cout<<string(SZ(A)+20,'-')<<endl;
  }
}

int main(){
  cin.tie(0);
  ios_base::sync_with_stdio(false);

  int N, K, C, T; cin >> N >> K >> C >> T;
  --C;
  VI as(K), bs(K), ts(K);
  Matrix A(5*N, Col(5*N));
  REP(i,N) REP(t,4)
	A[5*i+t][5*i+t+1]++;

  REP(i,K){
	cin >> as[i] >> bs[i] >> ts[i];
	--as[i];
	--ts[i];
	for(int k=0;k<bs[i];++k)
	  A[k*5+ts[i]][(as[i]+k)*5]++;
	for(int k=0;k<as[i];++k)
	  A[(bs[i]+k)*5+ts[i]][k*5]++;
	for(int k=as[i]+bs[i];k<N;++k)
	  A[5*k+ts[i]][5*k]++;
  }

  A = powA(A, T);
  cout << A[0][5*C] << endl;
  
  return 0;
}
accuracy: 1
time_ms: 670
memory_kb: 4168
final_rank: 10

code_snippet: #include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef complex<double> P;
typedef pair<int,int> pii;
#define REP(i,n) for(ll i=0;i<n;++i)
#define REPR(i,n) for(ll i=1;i<n;++i)
#define FOR(i,a,b) for(ll i=a;i<b;++i)

#define DEBUG(x) cout<<#x<<": "<<x<<endl
#define DEBUG_VEC(v) cout<<#v<<":";REP(i,v.size())cout<<" "<<v[i];cout<<endl
#define ALL(a) (a).begin(),(a).end()

#define ADD(a,b) a=((a)+(b))%MOD
#define FIX(a) ((a)%MOD+MOD)%MOD

const int mod = 1000000007;
const int logR = 30;
const int R = 1<<logR;
const int Rmask = R-1;
const int R2 = (int)((ll)R*R%mod);
int modash;
int MR(ll x){
    int m = (x*modash)&Rmask;
    int t = (x+(ll)m*mod)>>logR;
    if(t>=mod)t-=mod;
    return t;
}
int get_mod(ll x){return (int)MR((ll)MR(x)*R2);}
void init(){
    // R=1ll;logR=0;modash=0;
    // while(R<mod){R<<=1;logR++;}
    // R2=R*R%mod;
    int t=0,r=R,i=1;
    while(r>1){
        if((t&1)==0){t+=mod;modash+=i;}
        t>>=1;r>>=1;i<<=1;
    }
}

vector<vl> mul(vector<vl> a, vector<vl> b){
  int n = a.size();
  vector<vl> ret(n,vl(n,0));
  REP(k,n)REP(i,n)REP(j,n){
    ret[i][j] += get_mod(a[i][k]*b[k][j]);
    if(ret[i][j]>=mod) ret[i][j] -= mod;
  }
  return ret;
}

int main(){
  int n,k,c,t;
  scanf("%d%d%d%d",&n,&k,&c,&t);
  // ????§???????
  // 0?§???????1?§????...4?§????????£??????§??\?????????????????°t?????§?????¨?????????
  vector<vl> mat(5*n,vl(5*n,0));
  // ??????????§?
  REP(i,4){
    REP(j,n) mat[i*n+j][(i+1)*n+j] += 1;
  }
  // ?????????????§?
  REP(_,k){
    int a,b,tm;
    scanf("%d%d%d",&a,&b,&tm);
    // --a; --b;
    --tm;
    REP(i,n){
      int from;
      if(i<b) from = i+a-1;
      else if(i<b+a-1) from = i-b;
      else from = i;
      int to = i;
      mat[tm*n+to][from] += 1;
    }
  }
  // REP(po,5*n){
  //   DEBUG_VEC(mat[po]);
  // }
  // cout<<endl;
  init();
  // ?´????
  vector<vl> ans(5*n,vl(5*n,0));
  REP(i,5*n) ans[i][i]=1;
  while(t){
    if(t&1) ans = mul(ans,mat);
    mat = mul(mat,mat);
    t>>=1;
  }
  // DEBUG
  // REP(po,5*n){
  //   DEBUG_VEC(ans[po]);
  // }
  cout<<ans[0][c-1]<<endl;
  return 0;
}
accuracy: 1
time_ms: 2080
memory_kb: 2712
final_rank: 16

code_snippet: #include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef complex<double> P;
typedef pair<int,int> pii;
#define REP(i,n) for(ll i=0;i<n;++i)
#define REPR(i,n) for(ll i=1;i<n;++i)
#define FOR(i,a,b) for(ll i=a;i<b;++i)

#define DEBUG(x) cout<<#x<<": "<<x<<endl
#define DEBUG_VEC(v) cout<<#v<<":";REP(i,v.size())cout<<" "<<v[i];cout<<endl
#define ALL(a) (a).begin(),(a).end()

#define ADD(a,b) a=((a)+(b))%MOD
#define FIX(a) ((a)%MOD+MOD)%MOD

const int mod = 1000000007;
ll R,R2,modash;
int logR;
ll MR(ll x){
    ll ret = (x + (((x&(R-1ll))*modash)&(R-1ll))*mod)>>(logR);
    return (ret>=mod ? ret-mod : ret);
}
int get_mod(ll x){return (int)MR(MR(x)*R2);}
void init(){
    R=1ll;logR=0;modash=0;
    while(R<mod){R<<=1;logR++;}
    R2=R*R%mod;
    int t=0,r=R,i=1;
    while(r>1){
        if((t&1)==0){t+=mod;modash+=i;}
        t>>=1;r>>=1;i<<=1;
    }
}

vector<vl> mul(vector<vl> a, vector<vl> b){
  int n = a.size();
  vector<vl> ret(n,vl(n,0));
  REP(k,n)REP(i,n)REP(j,n){
    ret[i][j] += get_mod(a[i][k]*b[k][j]);
    if(ret[i][j]>=mod) ret[i][j] -= mod;
  }
  return ret;
}

int main(){
  int n,k,c,t;
  scanf("%d%d%d%d",&n,&k,&c,&t);
  // ????§???????
  // 0?§???????1?§????...4?§????????£??????§??\?????????????????°t?????§?????¨?????????
  vector<vl> mat(5*n,vl(5*n,0));
  // ??????????§?
  REP(i,4){
    REP(j,n) mat[i*n+j][(i+1)*n+j] += 1;
  }
  // ?????????????§?
  REP(_,k){
    int a,b,tm;
    scanf("%d%d%d",&a,&b,&tm);
    // --a; --b;
    --tm;
    REP(i,n){
      int from;
      if(i<b) from = i+a-1;
      else if(i<b+a-1) from = i-b;
      else from = i;
      int to = i;
      mat[tm*n+to][from] += 1;
    }
  }
  // REP(po,5*n){
  //   DEBUG_VEC(mat[po]);
  // }
  // cout<<endl;
  init();
  // ?´????
  vector<vl> ans(5*n,vl(5*n,0));
  REP(i,5*n) ans[i][i]=1;
  while(t){
    if(t&1) ans = mul(ans,mat);
    mat = mul(mat,mat);
    t>>=1;
  }
  // DEBUG
  // REP(po,5*n){
  //   DEBUG_VEC(ans[po]);
  // }
  cout<<ans[0][c-1]<<endl;
  return 0;
}
accuracy: 1
time_ms: 2510
memory_kb: 2712
final_rank: 18

code_snippet: #include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef complex<double> P;
typedef pair<int,int> pii;
#define REP(i,n) for(ll i=0;i<n;++i)
#define REPR(i,n) for(ll i=1;i<n;++i)
#define FOR(i,a,b) for(ll i=a;i<b;++i)

#define DEBUG(x) cout<<#x<<": "<<x<<endl
#define DEBUG_VEC(v) cout<<#v<<":";REP(i,v.size())cout<<" "<<v[i];cout<<endl
#define ALL(a) (a).begin(),(a).end()

#define ADD(a,b) a=((a)+(b))%MOD
#define FIX(a) ((a)%MOD+MOD)%MOD

const int mod = 1000000007;
ll R,R2,modash;
int logR;
ll MR(ll x){
    ll ret = (x + ((x*modash)&(R-1ll))*mod)>>(logR);
    return (ret>=mod ? ret-mod : ret);
}
ll get_mod(ll x){return MR(MR(x)*R2);}
void init(){
    R=1ll;logR=0;modash=0;
    while(R<mod){R<<=1;logR++;}
    R2=R*R%mod;
    int t=0,r=R,i=1;
    while(r>1){
        if((t&1)==0){t+=mod;modash+=i;}
        t>>=1;r>>=1;i<<=1;
    }
}

vector<vl> mul(vector<vl> a, vector<vl> b){
  int n = a.size();
  vector<vl> ret(n,vl(n,0));
  REP(k,n)REP(i,n)REP(j,n){
    ret[i][j] += get_mod(a[i][k]*b[k][j]);
    if(ret[i][j]>=mod) ret[i][j] -= mod;
  }
  return ret;
}

int main(){
  int n,k,c,t;
  scanf("%d%d%d%d",&n,&k,&c,&t);
  // ????§???????
  // 0?§???????1?§????...4?§????????£??????§??\?????????????????°t?????§?????¨?????????
  vector<vl> mat(5*n,vl(5*n,0));
  // ??????????§?
  REP(i,4){
    REP(j,n) mat[i*n+j][(i+1)*n+j] += 1;
  }
  // ?????????????§?
  REP(_,k){
    int a,b,tm;
    scanf("%d%d%d",&a,&b,&tm);
    // --a; --b;
    --tm;
    REP(i,n){
      int from;
      if(i<b) from = i+a-1;
      else if(i<b+a-1) from = i-b;
      else from = i;
      int to = i;
      mat[tm*n+to][from] += 1;
    }
  }
  // REP(po,5*n){
  //   DEBUG_VEC(mat[po]);
  // }
  // cout<<endl;
  init();
  // ?´????
  vector<vl> ans(5*n,vl(5*n,0));
  REP(i,5*n) ans[i][i]=1;
  while(t){
    if(t&1) ans = mul(ans,mat);
    mat = mul(mat,mat);
    t>>=1;
  }
  // DEBUG
  // REP(po,5*n){
  //   DEBUG_VEC(ans[po]);
  // }
  cout<<ans[0][c-1]<<endl;
  return 0;
}
accuracy: 1
time_ms: 2120
memory_kb: 2712
final_rank: 17