/* This solution represents states as a column vector. States represent the number of students of each type in group B. A transition matrix of size (s+1)*(c+1) x (s+1)*(c+1) is used to advance to the next state. Powers of the transition matrix jump the state ahead to the next masking time. Runtime O(p * log n * s^3 * c^3) -- Lawry */ #include #define rep(i,j,k) for (int i=j;i<(k);++i) using namespace std; typedef long long ll; typedef vector vll; typedef vector vvll; const ll MOD = 1e9+7; vvll matmul(const vvll&a, const vvll&b) { int r = a.size(); int p = b.size(); int c = b[0].size(); assert (p == a[0].size()); vvll ans(r, vll(c)); rep(i,0,r) rep(k,0,p) rep(j,0,c) ans[i][j] = (ans[i][j] + a[i][k] * b[k][j]) % MOD; return ans; } vvll matexp(vvll a, ll pow) { int n = a.size(); vvll ans(n, vll(n)); rep(i,0,n) ans[i][i] = 1; while (pow) { if (pow&1) ans = matmul(ans, a); a = matmul(a, a); pow >>= 1; } return ans; } int main() { ll n, p, s, c; cin >> n >> p >> s >> c; int num_states = (s+1)*(c+1); vvll trans(num_states, vll(num_states)); rep(i,0,s+1) rep(j,0,c+1) { int key = i*(c+1)+j; rep(di,-1,2) rep(dj,-1,2) { if (i + di < 0 || i+di > s || j+dj < 0 || j+dj > c) continue; int nkey = (i+di)*(c+1) + j + dj; ll add = 1; if (di<0) add *= i; else if (di>0) add *= (s-i); if (dj<0) add *= j; else if (dj>0) add *= (c-j); trans[nkey][key] = add; } } vvll states((s+1)*(c+1), vll(1)); states[0][0] = 1; ll curtime = 0; while (p--) { ll time; char side; int sl, cl, tl; cin >> time >> side >> sl >> cl >> tl; --time; states = matmul(matexp(trans, time-curtime), states); curtime = time; // apply mask here if (side == 'B') { rep(i,0,s+1) rep(j,0,c+1) if (i < sl || j < cl || i+j < tl) states[i*(c+1)+j][0] = 0; } else { rep(i,0,s+1) rep(j,0,c+1) if (s-i < sl || c-j < cl || s-i+c-j < tl) states[i*(c+1)+j][0] = 0; } } states = matmul(matexp(trans, n-1-curtime), states); cout << states[0][0] << endl; return 0; }