#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' : ' '); } |
English