CF869 C 组合

先吐槽下,题面套的物语系列欸..

由于距离为3,那么必定两种颜色间要填入第3种颜色,否则就是单独点的情况,那么两两之间可以单独考虑而不影响答案,枚举两种颜色之间边数,计算一边的组合和另一边的排列,最后把三种颜色间的组合情况都乘起来。

/** @Date    : 2017-10-09 15:44:12
  * @FileName: 869C.cpp
  * @Platform: Windows
  * @Author  : Lweleth (SoungEarlf@gmail.com)
  * @Link    : https://github.com/
  * @Version : $Id$
  */
#include <bits/stdc++.h>
#define LL long long
#define PII pair<int ,int>
#define MP(x, y) make_pair((x),(y))
#define fi first
#define se second
#define PB(x) push_back((x))
#define MMG(x) memset((x), -1,sizeof(x))
#define MMF(x) memset((x),0,sizeof(x))
#define MMI(x) memset((x), INF, sizeof(x))
using namespace std;

const int INF = 0x3f3f3f3f;
const int N = 1e5+20;
const double eps = 1e-8;
const LL mod = 998244353;
LL fac[5100];
LL inv[5100];

void init()
{
	fac[1] = fac[0] = 1;
	inv[1] = inv[0] = 1;
	for(int i = 2; i <= 5000; i++)
	{
		fac[i] = fac[i - 1] % mod * i % mod;
		inv[i] = (mod - mod / i) * inv[mod % i] % mod;
	}
	for(int i = 2; i <= 5000; i++)
		(inv[i] *= inv[i - 1]) %= mod; 
}

LL C(LL n, LL k)
{
	if(k > n)
		return 0;
	return fac[n] * inv[n - k] % mod * inv[k] % mod;
}

LL get(LL a, LL b)
{
	LL mi = min(a, b);
	LL ans = 0;
	for(int i = 0; i <= mi; i++)
		(ans += (C(a, i) % mod * (C(b, i) % mod * fac[i] % mod)) % mod) %= mod;
	return ans;
}
int main()
{
	LL a, b, c;
	init();
	cin >> a >> b >> c;
	cout << get(a, b) % mod * get(a, c) % mod * get(b, c) % mod << endl;
    return 0;
}
原文地址:https://www.cnblogs.com/Yumesenya/p/7642901.html