#include<bits/stdc++.h> using namespace std; using LL=long long; #define FOR(i,l,r)for(int i=(l);i<=(r);++i) #define REP(i,n)FOR(i,0,(n)-1) #define ssize(x)int(x.size()) #ifdef DEBUG auto operator<<(auto&o,auto x)->decltype(x.end(),o); auto&operator<<(auto&o,pair<auto,auto>p){return o<<"("<<p.first<<", "<<p.second<<")";} auto&operator<<(auto&o,tuple<auto,auto,auto>t){return o<<"("<<get<0>(t)<<", "<<get<1>(t)<<", "<<get<2>(t)<<")";} auto&operator<<(auto&o,tuple<auto,auto,auto,auto>t){return o<<"("<<get<0>(t)<<", "<<get<1>(t)<<", "<<get<2>(t)<<", "<<get<3>(t)<<")";} auto operator<<(auto&o,auto x)->decltype(x.end(),o){o<<"{";int i=0;for(auto e:x)o<<","+!i++<<e;return o<<"}";} #define debug(X...)cerr<<"["#X"]: ",[](auto...$){((cerr<<$<<"; "),...)<<endl;}(X) #else #define debug(...){} #endif constexpr int mod = int(1e9) + 7; int add(int a, int b) { a += b; return a >= mod ? a - mod : a; } void self_add(int& a, int b) { a = add(a, b); } int sub(int a, int b) { return add(a, mod - b); } int mul(int a, int b) { return int(a * LL(b) % mod); } int powi(int a, int b) { for(int ret = 1;; b /= 2) { if(b == 0) return ret; if(b & 1) ret = mul(ret, a); a = mul(a, a); } } int inv(int x) { return powi(x, mod - 2); } struct BinomCoeff { vector<int> fac, rev; BinomCoeff(int n) { fac = rev = vector(n + 1, 1); FOR(i, 1, n) fac[i] = mul(fac[i - 1], i); rev[n] = inv(fac[n]); for(int i = n; i > 0; --i) rev[i - 1] = mul(rev[i], i); } int operator()(int n, int k) { return mul(fac[n], mul(rev[n - k], rev[k])); } }; int main() { cin.tie(0)->sync_with_stdio(0); using T = vector<vector<int>>; int n, m, k; cin >> n >> m >> k; T v(k); REP(i, k) { REP(j, m) { char x; cin >> x; v[i].emplace_back(x == 'N'); } } debug(n, m, k, v); vector<int> ans(n + 1); FOR(d, k, n) { map<pair<int, T>, bool> cache; function<bool(int, const T&)> calc = [&](int player, const T& board) { auto it = cache.find(pair(player, board)); if (it != cache.end()) return it->second; bool ret = false; [&] { REP(i, ssize(board)) { REP(j, ssize(board[i])) { if (board[i][j] == player) { auto cp = board; cp[i].erase(cp[i].begin() + j, cp[i].end()); if (not calc(player ^ 1, cp)) { ret = true; return; } } } } }(); cache[pair(player, board)] = ret; debug(player, board, ret); return ret; }; v.resize(d, vector(m, 0)); const int len = d - k; const int N = len * m; REP(mask, 1 << N) { int p = 0; FOR(i, k, d - 1) { REP(j, m) { v[i][j] = (mask >> p) & 1; ++p; } } debug(d, mask, v); if (not calc(0, v) and not calc(1, v)) { self_add(ans[d], 1); } } } FOR(d, k, n) cout << ans[d] << (d == n ? '\n' : ' '); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | #include<bits/stdc++.h> using namespace std; using LL=long long; #define FOR(i,l,r)for(int i=(l);i<=(r);++i) #define REP(i,n)FOR(i,0,(n)-1) #define ssize(x)int(x.size()) #ifdef DEBUG auto operator<<(auto&o,auto x)->decltype(x.end(),o); auto&operator<<(auto&o,pair<auto,auto>p){return o<<"("<<p.first<<", "<<p.second<<")";} auto&operator<<(auto&o,tuple<auto,auto,auto>t){return o<<"("<<get<0>(t)<<", "<<get<1>(t)<<", "<<get<2>(t)<<")";} auto&operator<<(auto&o,tuple<auto,auto,auto,auto>t){return o<<"("<<get<0>(t)<<", "<<get<1>(t)<<", "<<get<2>(t)<<", "<<get<3>(t)<<")";} auto operator<<(auto&o,auto x)->decltype(x.end(),o){o<<"{";int i=0;for(auto e:x)o<<","+!i++<<e;return o<<"}";} #define debug(X...)cerr<<"["#X"]: ",[](auto...$){((cerr<<$<<"; "),...)<<endl;}(X) #else #define debug(...){} #endif constexpr int mod = int(1e9) + 7; int add(int a, int b) { a += b; return a >= mod ? a - mod : a; } void self_add(int& a, int b) { a = add(a, b); } int sub(int a, int b) { return add(a, mod - b); } int mul(int a, int b) { return int(a * LL(b) % mod); } int powi(int a, int b) { for(int ret = 1;; b /= 2) { if(b == 0) return ret; if(b & 1) ret = mul(ret, a); a = mul(a, a); } } int inv(int x) { return powi(x, mod - 2); } struct BinomCoeff { vector<int> fac, rev; BinomCoeff(int n) { fac = rev = vector(n + 1, 1); FOR(i, 1, n) fac[i] = mul(fac[i - 1], i); rev[n] = inv(fac[n]); for(int i = n; i > 0; --i) rev[i - 1] = mul(rev[i], i); } int operator()(int n, int k) { return mul(fac[n], mul(rev[n - k], rev[k])); } }; int main() { cin.tie(0)->sync_with_stdio(0); using T = vector<vector<int>>; int n, m, k; cin >> n >> m >> k; T v(k); REP(i, k) { REP(j, m) { char x; cin >> x; v[i].emplace_back(x == 'N'); } } debug(n, m, k, v); vector<int> ans(n + 1); FOR(d, k, n) { map<pair<int, T>, bool> cache; function<bool(int, const T&)> calc = [&](int player, const T& board) { auto it = cache.find(pair(player, board)); if (it != cache.end()) return it->second; bool ret = false; [&] { REP(i, ssize(board)) { REP(j, ssize(board[i])) { if (board[i][j] == player) { auto cp = board; cp[i].erase(cp[i].begin() + j, cp[i].end()); if (not calc(player ^ 1, cp)) { ret = true; return; } } } } }(); cache[pair(player, board)] = ret; debug(player, board, ret); return ret; }; v.resize(d, vector(m, 0)); const int len = d - k; const int N = len * m; REP(mask, 1 << N) { int p = 0; FOR(i, k, d - 1) { REP(j, m) { v[i][j] = (mask >> p) & 1; ++p; } } debug(d, mask, v); if (not calc(0, v) and not calc(1, v)) { self_add(ans[d], 1); } } } FOR(d, k, n) cout << ans[d] << (d == n ? '\n' : ' '); } |