#pragma GCC optimize("O2")
#include<bits/stdc++.h>
#define random randomA
#define ADD(a,b) (((a)+(b))>=mod ? (a)=((a)+(b)-mod) : (a)=((a)+(b)))
typedef long long ll;
using namespace std;
const int N=1610;
const ll mod=1000000007;
vector<int>a[N];
ll ans[N][N];
ll dp[N][N];
int nxt[N][2];
ll val[2][N][N][2][2];
ll val0[2][N][N][2];
int add[2][N];
bool have[N][2];
void calc(int type,int ind,vector<int>a){
int n=a.size();
for (int i=0;i<=n;i++) {
for (int j=0;j<=i;j++) dp[i][j]=0;
}
nxt[n][0]=n+1;
nxt[n][1]=n+1;
for (int i=n-1;i>=0;i--){
nxt[i][0]=nxt[i+1][0];
nxt[i][1]=nxt[i+1][1];
nxt[i][a[i]]=i+1;
}
dp[0][0]=1;
for (int i=0;i<n;i++){
for (int j=0;j<=i;j++){
ADD(dp[nxt[i][1]][j+1],dp[i][j]);
if (j) {
ADD(dp[nxt[i][0]][j-1],dp[i][j]);
}
}
}
for (int i=1;i<=n;i++){
ADD(add[type][ind],dp[i][0]);
for (int j=0;j<=i;j++){
ADD(val0[type][ind][j][a[i-1]],dp[i][j]);
if (nxt[i][0]==(n+1)){
ADD(val[type][ind][j][a[i-1]][0],dp[i][j]);
}
if (nxt[i][1]==(n+1)){
ADD(val[type][ind][j][a[i-1]][1],dp[i][j]);
}
}
}
}
void solve(){
int n;
cin>>n;
for (int i=1;i<=n;i++){
string s="";
cin>>s;
// for (int j=0;j<600;j++){
// if (rand()%2) s+="P";
// else s+="L";
// }
for (auto c:s){
if (c=='L') {
a[i].push_back(1);
have[i][1]=true;
}
else {
a[i].push_back(0);
have[i][0]=true;
}
}
}
for (int i=1;i<=n;i++){
calc(0,i,a[i]);
reverse(a[i].begin(),a[i].end());
for (int &j:a[i]) j^=1;
calc(1,i,a[i]);
reverse(a[i].begin(),a[i].end());
for (int &j:a[i]) j^=1;
}
for (int i=1;i<=n;i++){
for (int j=1;j<=n;j++){
ans[i][j]=add[0][i];
if (!have[i][1]){
(ans[i][j]+=add[1][j])%=mod;
}
for (int sum=0;sum<=min(a[i].size(),a[j].size());sum++){
ans[i][j]+=1ll*val[0][i][sum][0][1]*val0[1][j][sum][0];
ans[i][j]+=1ll*val[0][i][sum][1][1]*val0[1][j][sum][0];
ans[i][j]+=1ll*val[0][i][sum][1][0]*val0[1][j][sum][1];
ans[i][j]+=1ll*val[0][i][sum][0][0]*val0[1][j][sum][1];
ans[i][j]%=mod;
}
}
}
for (int i=1;i<=n;i++){
for (int j=1;j<=n;j++){
cout<<ans[i][j]<<" ";
}
cout<<'\n';
}
}
int main(){
ios_base::sync_with_stdio(false);
cin.tie(0);
int tt=1;
while (tt--){
solve();
}
return 0;
}
/*
LLP LLP
1
PPLP
LLP
2 2
4 3
*/
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 127 128 | #pragma GCC optimize("O2") #include<bits/stdc++.h> #define random randomA #define ADD(a,b) (((a)+(b))>=mod ? (a)=((a)+(b)-mod) : (a)=((a)+(b))) typedef long long ll; using namespace std; const int N=1610; const ll mod=1000000007; vector<int>a[N]; ll ans[N][N]; ll dp[N][N]; int nxt[N][2]; ll val[2][N][N][2][2]; ll val0[2][N][N][2]; int add[2][N]; bool have[N][2]; void calc(int type,int ind,vector<int>a){ int n=a.size(); for (int i=0;i<=n;i++) { for (int j=0;j<=i;j++) dp[i][j]=0; } nxt[n][0]=n+1; nxt[n][1]=n+1; for (int i=n-1;i>=0;i--){ nxt[i][0]=nxt[i+1][0]; nxt[i][1]=nxt[i+1][1]; nxt[i][a[i]]=i+1; } dp[0][0]=1; for (int i=0;i<n;i++){ for (int j=0;j<=i;j++){ ADD(dp[nxt[i][1]][j+1],dp[i][j]); if (j) { ADD(dp[nxt[i][0]][j-1],dp[i][j]); } } } for (int i=1;i<=n;i++){ ADD(add[type][ind],dp[i][0]); for (int j=0;j<=i;j++){ ADD(val0[type][ind][j][a[i-1]],dp[i][j]); if (nxt[i][0]==(n+1)){ ADD(val[type][ind][j][a[i-1]][0],dp[i][j]); } if (nxt[i][1]==(n+1)){ ADD(val[type][ind][j][a[i-1]][1],dp[i][j]); } } } } void solve(){ int n; cin>>n; for (int i=1;i<=n;i++){ string s=""; cin>>s; // for (int j=0;j<600;j++){ // if (rand()%2) s+="P"; // else s+="L"; // } for (auto c:s){ if (c=='L') { a[i].push_back(1); have[i][1]=true; } else { a[i].push_back(0); have[i][0]=true; } } } for (int i=1;i<=n;i++){ calc(0,i,a[i]); reverse(a[i].begin(),a[i].end()); for (int &j:a[i]) j^=1; calc(1,i,a[i]); reverse(a[i].begin(),a[i].end()); for (int &j:a[i]) j^=1; } for (int i=1;i<=n;i++){ for (int j=1;j<=n;j++){ ans[i][j]=add[0][i]; if (!have[i][1]){ (ans[i][j]+=add[1][j])%=mod; } for (int sum=0;sum<=min(a[i].size(),a[j].size());sum++){ ans[i][j]+=1ll*val[0][i][sum][0][1]*val0[1][j][sum][0]; ans[i][j]+=1ll*val[0][i][sum][1][1]*val0[1][j][sum][0]; ans[i][j]+=1ll*val[0][i][sum][1][0]*val0[1][j][sum][1]; ans[i][j]+=1ll*val[0][i][sum][0][0]*val0[1][j][sum][1]; ans[i][j]%=mod; } } } for (int i=1;i<=n;i++){ for (int j=1;j<=n;j++){ cout<<ans[i][j]<<" "; } cout<<'\n'; } } int main(){ ios_base::sync_with_stdio(false); cin.tie(0); int tt=1; while (tt--){ solve(); } return 0; } /* LLP LLP 1 PPLP LLP 2 2 4 3 */ |
English