#include <bits/stdc++.h> using namespace std; const int N = 605; const int mod = 1e9 + 7; int n, dp00[N][N], dp01[N][N], dp10[N][N], dp11[N][N], dp[N][N], su[N], ls[2], lp[2], suf[N][2], pre[N][2]; string s[N]; inline int inc(int x, int y) { x += y - mod; return x + (x >> 31 & mod); } inline int dec(int x, int y) { x -= y; return x + (x >> 31 & mod); } inline int mul(int x, int y) { return 1ll * x * y % mod; } auto inc(const auto &first, const auto ...args) { return inc(first, inc(args...)); } auto mul(const auto &first, const auto ...args) { return mul(first, mul(args...)); } inline void upd(int &x, int y) { x = inc(x, y); } inline void dpu(int &x, int y) { x = dec(x, y); } inline void pud(int &x, int y) { x = mul(x, y); } void init(string s) { int m = s.length(); ls[0] = ls[1] = lp[0] = lp[1] = -1; for (int i = m - 1; i >= 0; --i) { suf[i][0] = ls[0], suf[i][1] = ls[1]; if (s[i] == 'P') ls[1] = i; else ls[0] = i; } for (int i = 0; i < m; ++i) { pre[i][0] = lp[0], pre[i][1] = lp[1]; if (s[i] == 'P') lp[1] = i; else lp[0] = i; } } void ldp(string s, int t) { int m = s.length(); if (ls[0] == -1) { dp00[t][0] = 1; return; } for (int i = 0; i <= m; ++i) for (int j = 0; j <= m; ++j) dp[i][j] = 0; dp[ls[0]][1] = 1; for (int j = 0; j < m; ++j) { if (suf[j][0] != -1) { for (int k = 0; k <= j + 1; ++k) upd(dp[suf[j][0]][k + 1], dp[j][k]); } else { for (int k = 0; k <= j + 1; ++k) upd(dp00[t][k], dp[j][k]); } if (suf[j][1] != -1) { for (int k = 1; k <= j + 1; ++k) upd(dp[suf[j][1]][k - 1], dp[j][k]); } else { for (int k = 0; k <= j + 1; ++k) upd(dp01[t][k], dp[j][k]); } upd(su[t], dp[j][0]); } } void rdp(string s, int t) { int m = s.length(); if (lp[1] == -1) return; for (int i = 0; i <= m; ++i) for (int j = 0; j <= m; ++j) dp[i][j] = 0; dp[lp[1]][1] = 1; for (int j = m - 1; j >= 0; --j) { if (s[j] == 'P') { for (int k = 0; k <= m - j; ++k) upd(dp11[t][k], dp[j][k]); } else { for (int k = 0; k <= m - j; ++k) upd(dp10[t][k], dp[j][k]); } if (pre[j][0] != -1) { for (int k = 1; k <= m - j; ++k) upd(dp[pre[j][0]][k - 1], dp[j][k]); } if (pre[j][1] != -1) { for (int k = 0; k <= m - j; ++k) upd(dp[pre[j][1]][k + 1], dp[j][k]); } } } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); cin >> n; for (int i = 1; i <= n; ++i) { cin >> s[i]; } for (int t = 1; t <= n; ++t) { init(s[t]); ldp(s[t], t); rdp(s[t], t); } for (int i = 1; i <= n; ++i) { for (int j = 1; j <= n; ++j) { int ans = 0; for (int k = 0; k < N; ++k) { upd(ans, mul(dp00[i][k], dp10[j][k])); upd(ans, mul(dp01[i][k], dp11[j][k])); } cout << inc(su[i], ans) << " \n"[j == n]; } } return 0; }
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 120 121 122 123 124 125 126 | #include <bits/stdc++.h> using namespace std; const int N = 605; const int mod = 1e9 + 7; int n, dp00[N][N], dp01[N][N], dp10[N][N], dp11[N][N], dp[N][N], su[N], ls[2], lp[2], suf[N][2], pre[N][2]; string s[N]; inline int inc(int x, int y) { x += y - mod; return x + (x >> 31 & mod); } inline int dec(int x, int y) { x -= y; return x + (x >> 31 & mod); } inline int mul(int x, int y) { return 1ll * x * y % mod; } auto inc(const auto &first, const auto ...args) { return inc(first, inc(args...)); } auto mul(const auto &first, const auto ...args) { return mul(first, mul(args...)); } inline void upd(int &x, int y) { x = inc(x, y); } inline void dpu(int &x, int y) { x = dec(x, y); } inline void pud(int &x, int y) { x = mul(x, y); } void init(string s) { int m = s.length(); ls[0] = ls[1] = lp[0] = lp[1] = -1; for (int i = m - 1; i >= 0; --i) { suf[i][0] = ls[0], suf[i][1] = ls[1]; if (s[i] == 'P') ls[1] = i; else ls[0] = i; } for (int i = 0; i < m; ++i) { pre[i][0] = lp[0], pre[i][1] = lp[1]; if (s[i] == 'P') lp[1] = i; else lp[0] = i; } } void ldp(string s, int t) { int m = s.length(); if (ls[0] == -1) { dp00[t][0] = 1; return; } for (int i = 0; i <= m; ++i) for (int j = 0; j <= m; ++j) dp[i][j] = 0; dp[ls[0]][1] = 1; for (int j = 0; j < m; ++j) { if (suf[j][0] != -1) { for (int k = 0; k <= j + 1; ++k) upd(dp[suf[j][0]][k + 1], dp[j][k]); } else { for (int k = 0; k <= j + 1; ++k) upd(dp00[t][k], dp[j][k]); } if (suf[j][1] != -1) { for (int k = 1; k <= j + 1; ++k) upd(dp[suf[j][1]][k - 1], dp[j][k]); } else { for (int k = 0; k <= j + 1; ++k) upd(dp01[t][k], dp[j][k]); } upd(su[t], dp[j][0]); } } void rdp(string s, int t) { int m = s.length(); if (lp[1] == -1) return; for (int i = 0; i <= m; ++i) for (int j = 0; j <= m; ++j) dp[i][j] = 0; dp[lp[1]][1] = 1; for (int j = m - 1; j >= 0; --j) { if (s[j] == 'P') { for (int k = 0; k <= m - j; ++k) upd(dp11[t][k], dp[j][k]); } else { for (int k = 0; k <= m - j; ++k) upd(dp10[t][k], dp[j][k]); } if (pre[j][0] != -1) { for (int k = 1; k <= m - j; ++k) upd(dp[pre[j][0]][k - 1], dp[j][k]); } if (pre[j][1] != -1) { for (int k = 0; k <= m - j; ++k) upd(dp[pre[j][1]][k + 1], dp[j][k]); } } } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); cin >> n; for (int i = 1; i <= n; ++i) { cin >> s[i]; } for (int t = 1; t <= n; ++t) { init(s[t]); ldp(s[t], t); rdp(s[t], t); } for (int i = 1; i <= n; ++i) { for (int j = 1; j <= n; ++j) { int ans = 0; for (int k = 0; k < N; ++k) { upd(ans, mul(dp00[i][k], dp10[j][k])); upd(ans, mul(dp01[i][k], dp11[j][k])); } cout << inc(su[i], ans) << " \n"[j == n]; } } return 0; } |