https://codeforces.com/contest/869/C
题意:
有三种颜色的岛屿,数量分别为 \(A,B,C\)
在一些(可能全部或没有)岛屿之间建立了桥梁。一座桥双向连接两个不同的岛。对于任意两个相同颜色的岛甲和乙,要么甲不能到达乙,要么甲要经过至少3座桥才能到达乙
岛两两不同,问造桥方案总数。答案对 998244353 取模
思路:
两种不合法的造桥方式:\(a_i\leftrightarrow a_j\) 和 \(a_i\leftrightarrow b_k\leftrightarrow a_j\) ,其中 \(a_i\) 与 \(a_j\) 为两个同色岛,\(b_k\) 不同色
在 \(A\) 和 \(B\) 之间造桥不会影响在 \(B\) 和 \(C\) 之间造桥,也不会影响在 \(A\) 和 \(C\) 之间造桥
在 \(A\) 和 \(B\) 之间造桥的方案数为 \(f1=\Sigma_{k=0}^{min(A,B)} k!C_A^k C_B^k\) ,总方案数为 \(f1*f2*f3\)
\(A,B,C\le 5000\) ,可以预处理阶乘,快速幂求逆元
#include <bits/stdc++.h>
using namespace std;
const signed N = 5000;
const int p = 998244353;
int ksm(int a, int b)
{
a %= p;
int res = 1;
while(b)
{
if(b & 1) res = 1ll*res * a % p;
a = 1ll*a * a % p;
b >>= 1;
}
return res;
}
int jie[N+10];
void init()
{
jie[0] = 1;
for(int i = 1; i <= N; i++) jie[i]=1ll*i*jie[i-1]%p;
}
int inv(int x)
{
return ksm(x,p-2);
}
int C(int n, int m)
{
return 1ll*jie[n]*inv(1ll*jie[m]*jie[n-m]%p)%p;
}
int solve(int x, int y)
{
int ret = 0;
for(int i = 0; i <= min(x,y); i++)
ret=(ret+1ll*C(x,i)%p*C(y,i)%p*jie[i]%p)%p;
return ret;
}
signed main()
{
init();
int a, b, c; cin >> a >> b >> c;
cout << 1ll*solve(a,b)*solve(b,c)%p*solve(a,c)%p;
return 0;
}