提交时间:2026-05-27 16:04:38
运行 ID: 41684
#include<bits/stdc++.h> using namespace std; using ll=long long; using vi=vector<ll>; using vii=vector<vi>; using vi3=vector<vii>; using vi4=vector<vi3>; const int mod=1e9+7; int n,m;bool o=0; vii a;vii ans; void input(){ if(!o){ for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ char ch;cin>>ch; a[i][j]=ch-'0'; } } }else{ for(int i=1;i<=m;i++){ for(int j=1;j<=n;j++){ char ch;cin>>ch; a[j][i]=ch-'0'; } } } } void output(){ if(!o){ for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ char ch;cin>>ch; cout<<ans[i][j]<<' '; }cout<<'\n'; } }else{ for(int i=1;i<=m;i++){ for(int j=1;j<=n;j++){ cout<<ans[j][i]<<' '; }cout<<'\n'; } } } //vi4 f; int U; vii pre,suf; vi3 f;vi tmp; void clear(){for(auto &x:f)for(auto &y:x)for(auto &z:y)z=0;}; void getf(int i,int j,int o){ //0:1*1 1:x*1 2:1*x for(int k=0;k<=U;k++){ int s; //case 1 : 1*1 s=k|(1<<(j-1)); f[j][s][0]+=f[j-1][k][0]+f[j-1][k][1]+f[j-1][k][2]; //case 2 : x*1 if(a[i][j]==a[i][j-1]){ //case 2.1 : x*1 if(f[j-1][k][1]){ s=k&(U^(1<<(j-1))); f[j][s][1]+=f[j-1][k][1]; } //case 2.2 : 1*1 if(f[j-1][k][0]){ s=k&(U^(1<<(j-1)));s^=(1<<(j-2));//j-1 \neq 0 f[j][s][1]+=f[j-1][k][0]; } } //case 3 : 1*x if(a[i][j]==a[i-o][j]&&((k>>(j-1))&1)){ s=k; f[j][s][2]+=f[j-1][k][0]+f[j-1][k][1]+f[j-1][k][2]; } } for(int k=0;k<=U;k++){ f[j][k][0]%=mod;f[j][k][1]%=mod;f[j][k][2]%=mod; } }; void pre_dp(){ pre=vii(n+2,vi(U+10,0)); suf=vii(n+2,vi(U+10,0)); //get - pre clear();f[0][0][2]=1;pre[0][0]=1; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ getf(i,j,1);//u->d } for(auto &ed:tmp) ed=0; for(int j=0;j<=U;j++){ int now=0; for(int o=0;o<3;o++) now=(now+f[m][j][o])%mod; tmp[j]=now; }clear(); for(int j=0;j<=U;j++) f[0][j][2]=tmp[j]; for(int j=0;j<=U;j++) pre[i][j]=tmp[j]; } //get - suf clear();f[0][0][2]=1;suf[n+1][0]=1; for(int i=n;i>=1;i--){ for(int j=1;j<=m;j++){ getf(i,j,-1); } for(auto &ed:tmp) ed=0; for(int j=0;j<=U;j++){ int now=0; for(int o=0;o<3;o++) now=(now+f[m][j][o])%mod; tmp[j]=now; }clear(); for(int j=0;j<=U;j++) f[0][j][2]=tmp[j]; for(int j=0;j<=U;j++) suf[i][j]=tmp[j]; } } vi dp; void get_dp_val(int x,int y){ a[x][y]^=1; clear();for(int i=0;i<=U;i++) f[0][i][2]=pre[x-1][i]; for(int i=1;i<=m;i++){ getf(x,i,1); } for(auto &ed:tmp) ed=0; for(int j=0;j<=U;j++){ int now=0; for(int o=0;o<3;o++) now=(now+f[m][j][o])%mod; tmp[j]=now; }clear(); dp.resize(U+10); for(int j=0;j<=U;j++) dp[j]=tmp[j]; a[x][y]^=1; } void suffix_sum(vi &vec){ for(int i=0;i<m;i++){ for(int j=0;j<=U;j++){ if((j>>i)&1) continue; vec[j]=(vec[j]+vec[j+(1<<i)])%mod; } } } int calc_ans(int x,int y){ get_dp_val(x,y); //for(int i=0;i<=U;i++) cout<<i<<' '<<dp[i]<<' '<<suf[x+1][i]<<'\n'; suffix_sum(dp); int mark=0; a[x][y]^=1; for(int i=1;i<=m;i++) if(a[x][i]==a[x+1][i]) mark|=(1<<(i-1)); a[x][y]^=1; //cout<<mark<<'\n'; int ans=0; for(int i=0;i<=U;i++){ if((mark&i)!=i) continue; ans=(ans+1ll*dp[i]*suf[x+1][i])%mod; }return ans; } int main(){ //freopen("disanti.in","r",stdin); //freopen("disanti.out","w",stdout); cin>>n>>m; if(n<m) o=1,swap(n,m); a=vii(n+2,vi(m+2,0));ans=a; input();U=(1<<m)-1; f=vi3(m+2,vii(U+10,vi(3,0)));tmp=vi(U+10,0); pre_dp(); for(int i=1;i<=n+1;i++) suffix_sum(suf[i]); //f=vi4(n+2,vi3(m+2,vii(U+10,vi(3,0)))); for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ ans[i][j]=calc_ans(i,j); } } output(); return 0; }