#include <bits/stdc++.h> using namespace std; typedef long long lld; const unsigned MOD = 1e9+7; const int MAXN = 601; unsigned N, res[MAXN], suf[MAXN][2][MAXN], pref[MAXN][2][MAXN]; vector<bool> translate(const string &s) { vector<bool> v(s.size()); for (int i = 0; i < v.size(); ++i) v[i] = (s[i] == 'L'); return v; } vector<int> make_prev(const vector<bool> &v) { int p[2] {-1, -1}; vector<int> prev(v.size()); for (int i = 0; i < v.size(); ++i) { prev[i] = p[v[i]]; p[v[i]] = i; } return prev; } unsigned memo[2][MAXN]; void calc_dp(string &s, int idx) { vector<bool> v = translate(s); int n = v.size(); vector<vector<unsigned>> tab(n, vector<unsigned>(MAXN, 0u)); for (int i = 0; i < 2; ++i) for (int j = 0; j < MAXN; ++j) memo[i][j] = 0; memo[1][0] = 1; vector<int> prev = make_prev(v); for (int i = 0; i < n; ++i) { int dv = v[i] == 1 ? -1 : 1; for (int sum = 0; sum < MAXN; ++sum) tab[i][sum] = sum + dv < 0 || sum + dv >= n ? 0 : memo[v[i]][sum+dv]; for (int sum = 0; sum < MAXN; ++sum) { memo[v[i]][sum] = tab[i][sum]; memo[!v[i]][sum] += tab[i][sum]; if (memo[!v[i]][sum] >= MOD) memo[!v[i]][sum] -= MOD; } } for (int i = 0; i < MAXN; ++i) suf[idx][0][i] = memo[0][i], suf[idx][1][i] = memo[1][i]; int S = 0; for (int i = 0; i < n; ++i) { res[idx] += tab[i][0]; if (res[idx] >= MOD) res[idx] -= MOD; } vector<vector<unsigned>> rev(n, vector<unsigned>(MAXN, 0u)); for (int i = 0; i < n; ++i) rev[i][0] = 1; for (int i = n-1; i > 0; --i) { int dv = v[i] == 1 ? -1 : 1; for (int j = i-1; j >= 0 && j >= prev[i]; --j) { for (int sum = 0; sum < MAXN; ++sum) { if (sum + dv < 0 || sum + dv > n) continue; rev[j][sum+dv] += rev[i][sum]; if (rev[j][sum+dv] >= MOD) rev[j][sum+dv] -= MOD; } } } for (int i = 0; i < MAXN; ++i) pref[idx][v[0]][i] = rev[0][i]; int pos = 1; while (pos < n && v[pos] == v[0]) ++pos; if (pos == n) return; for (int i = 0; i < MAXN; ++i) pref[idx][v[pos]][i] = rev[pos][i]; } unsigned merge(int i1, int i2) { unsigned S = res[i1]; for (int sum = 0; sum + 1 < MAXN; ++sum) S = ((lld)S + (lld)suf[i1][0][sum + 1] * (lld)pref[i2][0][sum]) % (lld)MOD; for (int sum = 1; sum < MAXN; ++sum) S = ((lld)S + (lld)suf[i1][1][sum - 1] * (lld)pref[i2][1][sum]) % (lld)MOD; return S; } // (0, 0) -> (n, 0) int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); cin >> N; string s; for (int i = 0; i < N; ++i) { cin >> s; calc_dp(s, i); } for (int i = 0; i < N; ++i) { for (int j = 0; j < N; ++j) cout << merge(i, j) << ' '; cout << '\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 | #include <bits/stdc++.h> using namespace std; typedef long long lld; const unsigned MOD = 1e9+7; const int MAXN = 601; unsigned N, res[MAXN], suf[MAXN][2][MAXN], pref[MAXN][2][MAXN]; vector<bool> translate(const string &s) { vector<bool> v(s.size()); for (int i = 0; i < v.size(); ++i) v[i] = (s[i] == 'L'); return v; } vector<int> make_prev(const vector<bool> &v) { int p[2] {-1, -1}; vector<int> prev(v.size()); for (int i = 0; i < v.size(); ++i) { prev[i] = p[v[i]]; p[v[i]] = i; } return prev; } unsigned memo[2][MAXN]; void calc_dp(string &s, int idx) { vector<bool> v = translate(s); int n = v.size(); vector<vector<unsigned>> tab(n, vector<unsigned>(MAXN, 0u)); for (int i = 0; i < 2; ++i) for (int j = 0; j < MAXN; ++j) memo[i][j] = 0; memo[1][0] = 1; vector<int> prev = make_prev(v); for (int i = 0; i < n; ++i) { int dv = v[i] == 1 ? -1 : 1; for (int sum = 0; sum < MAXN; ++sum) tab[i][sum] = sum + dv < 0 || sum + dv >= n ? 0 : memo[v[i]][sum+dv]; for (int sum = 0; sum < MAXN; ++sum) { memo[v[i]][sum] = tab[i][sum]; memo[!v[i]][sum] += tab[i][sum]; if (memo[!v[i]][sum] >= MOD) memo[!v[i]][sum] -= MOD; } } for (int i = 0; i < MAXN; ++i) suf[idx][0][i] = memo[0][i], suf[idx][1][i] = memo[1][i]; int S = 0; for (int i = 0; i < n; ++i) { res[idx] += tab[i][0]; if (res[idx] >= MOD) res[idx] -= MOD; } vector<vector<unsigned>> rev(n, vector<unsigned>(MAXN, 0u)); for (int i = 0; i < n; ++i) rev[i][0] = 1; for (int i = n-1; i > 0; --i) { int dv = v[i] == 1 ? -1 : 1; for (int j = i-1; j >= 0 && j >= prev[i]; --j) { for (int sum = 0; sum < MAXN; ++sum) { if (sum + dv < 0 || sum + dv > n) continue; rev[j][sum+dv] += rev[i][sum]; if (rev[j][sum+dv] >= MOD) rev[j][sum+dv] -= MOD; } } } for (int i = 0; i < MAXN; ++i) pref[idx][v[0]][i] = rev[0][i]; int pos = 1; while (pos < n && v[pos] == v[0]) ++pos; if (pos == n) return; for (int i = 0; i < MAXN; ++i) pref[idx][v[pos]][i] = rev[pos][i]; } unsigned merge(int i1, int i2) { unsigned S = res[i1]; for (int sum = 0; sum + 1 < MAXN; ++sum) S = ((lld)S + (lld)suf[i1][0][sum + 1] * (lld)pref[i2][0][sum]) % (lld)MOD; for (int sum = 1; sum < MAXN; ++sum) S = ((lld)S + (lld)suf[i1][1][sum - 1] * (lld)pref[i2][1][sum]) % (lld)MOD; return S; } // (0, 0) -> (n, 0) int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); cin >> N; string s; for (int i = 0; i < N; ++i) { cin >> s; calc_dp(s, i); } for (int i = 0; i < N; ++i) { for (int j = 0; j < N; ++j) cout << merge(i, j) << ' '; cout << '\n'; } } |