You are given an integer xx and an array of integers a1,a2,…,ana1,a2,…,an. You have to determine if the number a1!+a2!+…+an!a1!+a2!+…+an! is divisible by x!x!.
Here k!k! is a factorial of kk — the product of all positive integers less than or equal to kk. For example, 3!=1⋅2⋅3=63!=1⋅2⋅3=6, and 5!=1⋅2⋅3⋅4⋅5=1205!=1⋅2⋅3⋅4⋅5=120.
Input
The first line contains two integers nn and xx (1≤n≤5000001≤n≤500000, 1≤x≤5000001≤x≤500000).
The second line contains nn integers a1,a2,…,ana1,a2,…,an (1≤ai≤x1≤ai≤x) — elements of given array.
Output
In the only line print "Yes" (without quotes) if a1!+a2!+…+an!a1!+a2!+…+an! is divisible by x!x!, and "No" (without quotes) otherwise.
题意:给出n个数,判断这n个数的阶乘之和能否被k的阶乘整除。
分析:暴力肯定过不了,数据太大了。
引理:1*1!+2*2!+3*3!+......+n*n! < (n+1)!
证明:只需要每次把左边的最后一项移动到右边进行合并,最后剩下1*1! < 2*2!,显然成立。
思路:
可以统计每个数的阶乘的个数。从前往后,如果有i+1个就把i的阶乘转化为i+1的阶乘。以此类推,最后会得到p*k!+ ∑ q * i!。由引理可知,∑ q * i!小于k!,而p*k!的阶乘又一定可以被k!整除,因此只需要判断cnt[i]%(i+1)是否为0即可。
#include<iostream>
#include<vector>
#include<cstdio>
using namespace std;
const int N = 5e5 + 5;
int cnt[N];
int main() {
int n, x, a;
cin >> n >> x;
for(int i = 1; i <= n; ++ i){
cin >> a;
cnt[a] ++; //统计a的阶乘的个数
}
for(int i = 1; i < x; ++ i){
if(cnt[i] % (i+1)){ //判断
puts("No"); //cout << i << ' ' << cnt[i] << endl;
return 0;
}
cnt[i+1] += cnt[i] / (i+1); //转化
}
puts("Yes");
return 0;
}