#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 */ |