题目:H-Permutation Counting_MINIEYE杯第十六届华中科技大学程序设计邀请赛 (nowcoder.com)
思路:
#include <bits/stdc++.h> using namespace std; #define ri register int #define M 2000006 vector <int> p[M]; vector <int> q; int n,m; int vis[M]; int sz[M]; void dfs1(int a) { vis[a]=1; sz[a]++; for(ri i=0;i<p[a].size();i++) { int b=p[a][i]; dfs1(b); sz[a]+=sz[b]; } return ; } long long ans=1; const int mod=998244353; int in[M]; long long arr[M],inv[M]; long long ksn(long long a,int n) { long long ans=1; while(n) { if(n&1) ans=ans*a%mod; n>>=1;a=a*a%mod; } return ans; } void init(){ arr[0]=1;inv[0]=1; for(ri i=1;i<=n;i++) { arr[i]=arr[i-1]*i%mod; inv[i]=ksn(arr[i],mod-2); } } long long zh(int a,int b) { if(a<b) return 0; if(a==b||b==0) return 1; return arr[a]*inv[a-b]%mod*inv[b]%mod; } void dfs2(int a) { int tmp=sz[a]-1; for(ri i=0;i<p[a].size();i++) { int b=p[a][i]; ans=(ans*zh(tmp,sz[b]))%mod; tmp-=sz[b]; dfs2(b); } } int main(){ ios::sync_with_stdio(false); cin.tie(0); cin>>n>>m; init(); for(ri i=1;i<=m;i++) { int a,b; cin>>a>>b; p[b].push_back(a); in[a]++; } for(ri i=1;i<=n;i++) { if(in[i]==0) { q.push_back(i); } } for(ri i=0;i<q.size();i++) { int b=q[i]; dfs1(b); } for(ri i=1;i<=n;i++) { if(vis[i]==0) { printf("0\n"); return 0; } } int tmp=n; for(ri i=0;i<q.size();i++) { int a=q[i]; ans=(ans*zh(tmp,sz[a]))%mod; dfs2(a); tmp-=sz[a]; } cout<<ans; return 0; }View Code