Factorial Divisibility(多个数的阶乘之后是否整除另一个数的阶乘)

题意:

给定n个数a1,a2,…,an和数x
问a1!+a2!+…+an!是否可以被x!整除

Input

The first line contains two integers nn and xx (1 \le n \le 500\,0001≤n≤500000, 1 \le x \le 500\,0001≤x≤500000).

The second line contains nn integers a_1, a_2, \ldots, a_na1​,a2​,…,an​ (1 \le a_i \le x1≤ai​≤x) — elements of given array.

Output

In the only line print "Yes" (without quotes) if a_1! + a_2! + \ldots + a_n!a1​!+a2​!+…+an​! is divisible by x!x!, and "No" (without quotes) otherwise.

Sample 1

InputcopyOutputcopy
6 4
3 2 2 2 3 3
Yes

Sample 2

InputcopyOutputcopy
8 3
3 2 2 2 2 2 1 1
Yes

Sample 3

InputcopyOutputcopy
7 8
7 7 7 7 7 7 7
No

Sample 4

InputcopyOutputcopy
10 5
4 3 2 1 4 3 2 4 3 4
No

Sample 5

InputcopyOutputcopy
2 500000
499999 499999
No

题解:

1.ct[]表示小于x的a的阶乘和,用ct[] 数组记录每个给出的小于x的数的出现次数(大于等于x的一定可以整除),即 ct[a_{i}]++

2.当ct[a]>a+1时,即a出现的次数大于 a+1 时,进行操作:ct[a]=ct[a]-a-1;ct[a+1]=ct[a+1]+1;

解释:因为下标代表的是a的阶层,则 a!*(a+1)=(a+1)!.所以操作后,这n个数的总和不变。

3.如果这些小于x的数的阶乘之和可以整除x的话,那么它们的可可以表示=k*x!。k为大于0的任意整数。表现在ct数组上,即为当i<x,ct[i]==0;

#include <iostream>
#include <cstring>
using namespace std;
const long long N = 5e5 + 100;
int  ct[N];

int main()
{
	int n, x,v;
	cin >> n >> x;

	for (int i = 1; i <= n; i++)
	{
		cin >> v;
		if(v<x)
		ct[v]++;

	}
	int f = 1;

	for (int  i = 1; i < x; i++)
	{
		if (ct[i] >= i + 1)
		{
			
			ct[i + 1] = ct[i + 1] + ct[i]/(i+1);
			ct[i] = ct[i] - ct[i] / (i + 1) * (i + 1);
		}
		if (ct[i] != 0)
		{
			f = 0;
			cout << "No" << endl;
			break;
		}
	}
	if (f)
		cout << "Yes" << endl;
}

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

linalw

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值