ARC163D Sum of SCC
Description
设 表示竞赛图 中的强连通分量数量。计算所有下列条件的
的 之和:
答案对 取模。
。
Sol
竞赛图缩点之后必定可以划分成两个集合 使 中任意两点 都存在边 。
那么任意一个竞赛图的权值就是把图中元素分为 两个集合满足上述条件的方案数 。
定义 表示前 个点中 个点被分在了集合 且恰好有
条边从小编号结点指向大编号结点的方案数。
则很容易写出转移: 时间复杂度 。
Code
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
| #include<bits/stdc++.h> #define int long long const int N=35; const int M=505; const int Mod=998244353; template<typename Tp=int>inline Tp read(){Tp x(0);int op(0);char ch=getchar();while(ch<'0'||ch>'9')op|=(ch==45),ch=getchar();while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+(ch^48),ch=getchar();return op?-x:x;} int f[N][N][M]; int n,m; int fac[M],inv[M]; int ksm(int x,int y){ int ans=1; for(;y;y>>=1,x=x*x%Mod)if(y&1)ans=ans*x%Mod; return ans; } void init(){ fac[0]=inv[0]=1; for(int i=1;i<M;++i)fac[i]=fac[i-1]*i%Mod,inv[i]=ksm(fac[i],Mod-2); } int C(int x,int y){return x<y||x<0||y<0?0:fac[x]*inv[y]%Mod*inv[x-y]%Mod;} signed main(){ n=read();m=read(); init(); f[0][0][0]=1; for(int i=0;i<n;++i) for(int j=0;j<=i;++j) for(int k=0;k<=m;++k){ for(int l=0;l<=j;++l)(f[i+1][j+1][k+l]+=f[i][j][k]*C(j,l))%=Mod; for(int l=0;l<=i-j;++l)(f[i+1][j][k+l+j]+=f[i][j][k]*C(i-j,l))%=Mod; } int ans=0; for(int i=1;i<=n;++i)(ans+=f[n][i][m])%=Mod; printf("%lld\n",ans); return 0; }
|