提交时间:2025-06-22 16:51:35

运行 ID: 38106

#include<bits/stdc++.h> using namespace std; const int N=20,MS=35000,mod=998244353; void Add(int &a,int b){a+=b;if(a>=mod) a-=mod;} void Sub(int &a,int b){a-=b;if(a<0) a+=mod;} void Mul(int &a,int b){a=1ll*a*b%mod;} int f[N][MS],tf[N][MS];//count-tmp int g[N][MS],tg[N][MS];//num-tmp int h[N][MS],dc[N][N];//decval int a[N][N]; int n; bool next_subset(int &a,int b){ if(!a) return 0; a=(a-1)&b;return 1; } namespace fmt{ void FMT(int *arr,int n,int op){ int U=(1<<n)-1; for(int i=0;i<n;i++){ for(int j=0;j<=U;j++){ if((j>>i)&1) continue; if(op==1) Add(arr[j|(1<<i)],arr[j]); if(op==-1) Sub(arr[j|(1<<i)],arr[j]); } } } }; using namespace fmt; /* namespace poly{ void mul(int *arr,int n,int value,int shift){ for(int i=n;i>=0;i--){ if(i+shift>n) continue; int val=1ll*value*arr[n]%mod; Add(arr[i+shift],val); } } }; using namespace poly; */ #define ppc __builtin_popcount int tmp[N][MS],trf[N][N][MS],trg[N][N][MS]; //id-set,id-power-set int main(){ cin>>n; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ cin>>a[i][j]; } } int U=(1<<n)-1; memset(f,0,sizeof(f)); memset(tf,0,sizeof(tf)); memset(trf,0,sizeof(trf)); for(int i=1;i<=n;i++) tf[i][0]=1; for(int pw=0;pw<=n;pw++){ //cout<<pw<<endl; for(int i=1;i<=U;i++){ //cout<<i<<endl; if(ppc(i)!=pw) continue; for(int j=1;j<=n;j++){ if(!((i>>(j-1))&1)) continue; int S=i^(1<<(j-1)); Add(f[j][i],tmp[j][S]); //cout<<"f:"<<j<<' '<<i<<' '<<f[j][i]<<' '<<tmp[j][S]<<endl; /* int T=S; do{ int O=S^T; Add(f[j][i],1ll*tf[j][T]*tf[j][O]%mod); }while(next_subset(T,S)); */ for(int k=1;k<=n;k++){ if((i>>(k-1))&1) continue; if(a[k][j]) Add(tf[k][i],f[j][i]); } } } memset(tmp,0,sizeof(tmp)); for(int j=1;j<=n;j++){ //cout<<tf[j][0]<<endl; FMT(tf[j],n,1); for(int i=0;i<=U;i++){ Add(trf[j][pw][i],tf[j][i]); } for(int p=0;p<=pw;p++){ for(int i=0;i<=U;i++){ Add(tmp[j][i],1ll*trf[j][p][i]*trf[j][pw-p][i]%mod); } } FMT(tmp[j],n,-1); }//may swap(p,i) memset(tf,0,sizeof(tf)); } for(int i=1;i<=n;i++) tf[i][0]=1; for(int i=1;i<=U;i++){ for(int j=1;j<=n;j++){ if(!((i>>(j-1))&1)) continue; for(int k=1;k<=n;k++){ if((i>>(k-1))&1) continue; if(a[k][j]) Add(tf[k][i],f[j][i]); } } }//tf->f after memset(g,0,sizeof(g)); memset(tg,0,sizeof(tg)); /* memset(trg,0,sizeof(trg)); memset(tmp,0,sizeof(tmp)); g[1][U^U]=1; //rev g for(int pw=0;pw<=n;pw++){ for(int i=U;i>=0;i--){ if(ppc(i^U)!=pw) continue; for(int j=1;j<=n;j++){ if(((i^U)>>(j-1))&1) continue; int S=i^(1<<(j-1)),T=S; Add(tg[j][i],2ll*tmp[j][S]%mod); /* do{ int A=i|T|(1<<(j-1)); Add(tg[j][i],2ll*tf[j][T]*g[j][A]%mod); }while(next_subset(T,S)); * / for(int k=1;k<=n;k++){ if(!(((i^U)>>(k-1))&1)) continue; if(a[j][k]) Add(g[k][i^U],tg[j][i]); } } }for(int j=1;j<=n;j++){ FMT(g[j],n,1); for(int i=0;i<=U;i++){ Add(trg[j][pw][i],g[j][i]); } for(int p=0;p<=pw;p++){ for(int i=0;i<=U;i++){ Add(tmp[j][i],1ll*trf[j][p][i]*trg[j][pw-p][i]%mod); } }FMT(tmp[j],n,-1); }memset(g,0,sizeof(g)); }*/ /* for(int i=U;i>=0;i--){ for(int j=1;j<=n;j++){ if((i>>(j-1))&1) continue; for(int k=1;k<=n;k++){ if(!((i>>(k-1))&1)) continue; if(a[j][k]) Add(g[k][i],tg[j][i]); } } }*/ memset(g,0,sizeof(g)); memset(tg,0,sizeof(tg)); g[1][U]=1; for(int i=U;i>=1;i--){ for(int j=1;j<=n;j++){ if((i>>(j-1))&1) continue; int S=U^i^(1<<(j-1)),T=S; do{ int A=i|T|(1<<(j-1)); Add(tg[j][i],2ll*tf[j][T]*g[j][A]%mod); }while(next_subset(T,S)); //cout<<"tg:"<<j<<' '<<i<<' '<<tg[j][i]<<endl; for(int k=1;k<=n;k++){ if(!((i>>(k-1))&1)) continue; if(a[j][k]) Add(g[k][i],tg[j][i]); //cout<<"to:"<<k<<' '<<tg[j][i]<<endl; } } } memset(h,0,sizeof(h)); for(int i=1;i<=U;i++){ for(int j=1;j<=n;j++){ if((i>>(j-1))&1) continue; int S=U^i^(1<<(j-1)),T=S; do{ int A=i|T|(1<<(j-1)); Add(h[j][i],2ll*tf[j][T]*g[j][A]%mod); }while(next_subset(T,S)); for(int k=1;k<=n;k++){ if(!((i>>(k-1))&1)) continue; if(a[j][k]) Sub(dc[j][k],1ll*h[j][i]*f[k][i]%mod); } } } cout<<f[1][U]<<endl; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ int ans=dc[i][j]; for(int k=1;k<=U;k++){ if((k>>(j-1))&1) Add(ans,1ll*f[i][k]*g[i][k]%mod); } if(!a[i][j]) ans=0; cout<<ans<<' '; }cout<<endl; } return 0; }