G - Shinyruo and KFC Gym - 103428G

G - Shinyruo and KFC Gym - 103428G

题意

给你n种不同的食物,每种食物有 a i a_i ai多个,食物个数不超过1e5,现在一共有m个人, 1 ≤ k ≤ m 1 \le k \le m 1km ,每种食物最多拿一个,每个人可以拿多种食物,输出食物分配方案。

思路

关键语句,食物个数不超过1e5,说明给你的数据会有很多重复的样例,对于每个重复的样例我们可以采用快速幂这样累加答案,而且去重过后的数组长度不会太大,所以完全可以写暴力。枚举人数来写。

代码

在这里插#include<bits/stdc++.h>

#define IOS ios::sync_with_stdio(false);cin.tie(nullptr)
#define int long long 

using namespace std;

const int N = 1e5 + 100, mod = 998244353;


int arr[N], sum[N], fac[N], infac[N];

int ksm(int a, int b)//快速幂
{
	int ans = 1;
	while (b)
	{
		if (b & 1) ans = (ans * a) % mod;
		a = (a * a) % mod;
		b >>= 1;
	}
	return ans;
}

int C(int n, int m)//组合数公式
{
	if (m < 0 || n < m) return 0;
	return fac[n] * infac[m] % mod * infac[n - m] % mod;
}

void init()//预处理阶乘,逆元
{
	fac[0] = 1;
	for (int i = 1; i <= N - 1; i++) fac[i] = (fac[i - 1] * i) % mod;
	for (int i = 0; i <= N - 1; i++) infac[i] = ksm(fac[i], mod - 2);
}

signed main()
{
	IOS;
	init();
	int n, m;
	cin >> n >> m;
	for (int i = 1; i <= n; i++) cin >> arr[i], sum[arr[i]]++;

	sort(arr + 1, arr + 1 + n);//排序不影响结果,每个数都会算到的
	int r = unique(arr + 1, arr + 1 + n) - arr - 1;//去重,也可以选用map
	
	int l = 1;
	while (arr[l] == 0) l++;//找到第一个不为0的数,题目说了
	
	for (int i = 1; i <= m; i++)
	{
		int ans = 1;
		for (int j = l; j <= r; j++) ans = (ans * ksm( C(i, arr[j]), sum[arr[j]]) ) % mod;
		cout << ans % mod << endl;
	}
	return 0;
}入代码片
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值