CF715E
- 對於全部確定的情況,算出 n - 環數 即可
對於全部不確定的情況,ansi=sn,in!
否則考慮 pi 向 qi 連邊,原圖相當於若干條鏈(以及環,已經成環可以不管了),形如 (0,0),(a,0),(0,a),(a,b),對於第 4 類對方案數沒有貢獻
分類記爲 a,b,c,b 類可以自己和自己拼接,枚舉其個數以及環數,剩餘的考慮與 (0,0) 拼接,注意到 (a,0) 可以與 (0,0) 拼接成 (0,0),寫成對其環個數的 OGF
拼接時 b 帶標號,先讓 a 無標號,最後考慮其標號,方案數是個插板
F(x)=i=0∑bxij=i∑b(jb)sj,i(j−ia−1+j−i)(j−i)!
c 類同理,a 類的 OGF 也可以簡單寫出(考慮標號)
G(x)=i=0∑aa!sa,ixi
#include<bits/stdc++.h>
#define cs const
#define pb push_back
using namespace std;
cs int Mod = 998244353;
int add(int a, int b){ return a + b >= Mod ? a + b - Mod : a + b; }
int dec(int a, int b){ return a - b < 0 ? a - b + Mod : a - b; }
int mul(int a, int b){ return 1ll * a * b % Mod; }
void Mul(int &a, int b){ a = mul(a,b); }
void Add(int &a, int b){ a = add(a,b); }
void Dec(int &a, int b){ a = dec(a,b); }
int ksm(int a, int b){ int as=1; for(;b;b>>=1,Mul(a,a))if(b&1)Mul(as,a); return as; }
cs int N = 5e3 + 50;
int n, a[N], b[N], in[N], out[N];
int A, B, C, D, to[N];
int S[N][N], f[N], g[N], h[N];
int fc[N], ifc[N];
int Binom(int n, int m){ if(n<0||m<0||n<m) return 0; return mul(fc[n],mul(ifc[n-m],ifc[m])); }
int anc[N], sz[N], ec[N];
int fnd(int x){ return x == anc[x] ? x : anc[x] = fnd(anc[x]); }
void mrg(int x, int y){
int fx = fnd(x), fy = fnd(y); ++ec[fx];
if(fx==fy) return;
ec[fx]+=ec[fy]; sz[fx]+=sz[fy];
anc[fy] = fx;
}
int main(){
#ifdef FSYolanda
freopen("1.in","r",stdin);
#endif
scanf("%d",&n);
for(int i=1; i<=n; i++)
scanf("%d",&a[i]);
for(int i=1; i<=n; i++)
scanf("%d",&b[i]);
for(int i=1; i<=n; i++) anc[i]=i,sz[i]=1;
for(int i=1; i<=n; i++) if(a[i] && b[i]) mrg(a[i],b[i]);
static bool ea[N], eb[N], da[N], db[N];
for(int i=1,u,v; i<=n; i++){
u=fnd(a[i]),v=fnd(b[i]);
if(a[i] && b[i] && u==v){
if(u==a[i] && ec[u]==sz[u]) ++D;
} a[i]=u; b[i]=v;
if(a[i] && b[i]!=a[i])
ea[a[i]] = true, da[a[i]] = !!b[i];
if(b[i] && b[i]!=a[i])
eb[b[i]] = true, db[b[i]] = !!a[i];
}
for(int i=1; i<=n; i++)
if(!a[i] && !b[i]) ++A;
for(int i=1; i<=n; i++){
if(ea[i] && eb[i] && !da[i] && !db[i]) ++A;
else{
if(ea[i] && !da[i]) ++B;
if(eb[i] && !db[i]) ++C;
}
}
S[0][0] = 1;
for(int i=1; i<=n; i++)
for(int j=1; j<=i; j++)
S[i][j]=add(S[i-1][j-1],mul(S[i-1][j],i-1));
fc[0]=ifc[0]=fc[1]=ifc[1]=1;
for(int i=2; i<=n; i++) fc[i]=mul(fc[i-1],i);
ifc[n]=ksm(fc[n],Mod-2);
for(int i=n-1; i>=2; i--) ifc[i]=mul(ifc[i+1],i+1);
for(int i=0; i<=B; i++){
if(!A) f[i]=S[B][i];
else for(int j=i; j<=B; j++)
Add(f[i],mul(mul(Binom(B,j),S[j][i]),mul(Binom(A-1+B-j,A-1),fc[B-j])));
}
for(int i=0; i<=C; i++){
if(!A) g[i]=S[C][i];
else for(int j=i; j<=C; j++)
Add(g[i],mul(mul(Binom(C,j),S[j][i]),mul(Binom(A-1+C-j,A-1),fc[C-j])));
}
static int ans[N], tmp[N];
for(int i=0; i<=B; i++)
for(int j=0; j<=C; j++)
Add(tmp[i+j],mul(f[i],g[j]));
for(int i=0; i<=A; i++)
h[i] = mul(fc[A],S[A][i]);
for(int i=0; i<=B+C; i++)
for(int j=0; j<=A; j++)
Add(ans[i+j],mul(h[j],tmp[i]));
for(int i=n; i>=D; i--) ans[i] = ans[i-D];
for(int i=D-1; i>=0; i--) ans[i] = 0;
for(int i=0; i<n; i++)
cout<<ans[n-i]<<" ";
return 0;
}