【题解】CF1753B Factorial Divisibility
题面传送门
解决思路
先手算一下样例,可以发现,\(i+1\) 个 \(i!\) 相加等于 \((i+1)\times i!= (i+1)!\)。所以考虑把可以合并的都合并。
因为 \(a_i\le 500000\),所以只需用桶计数,从 \(1\) 到 \(500000\) 扫一遍,发现满足条件的就向后一位进位。 然后我们就得到了原数列最简形式。
考虑两个数 \(x,y\),当 \(x\ge y\) 时,\(x!\) 显然可以被 \(y!\) 整除,因为 \(x!=y!\times(y+1)\times \dots \times x\)。同理,对于另一个 \(z\ge y\),\(x!+z!\) 也一定可以被 \(y!\) 整除。其实就是乘法分配律。反之,对于 \(t<y\),则 \(t!\) 不能被 \(y!\) 整除,\(x!+z!+t!\) 也就不能被 \(y!\) 整除了。
所以我们得出,若最简序列中最小 \(a_i\) 的若小于 \(x\),则最后的和显然无法被 \(x!\) 整除。
AC Code
#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(false)
#define TIE cin.tie(0),cout.tie(0)
#define int long long
#define double long double
using namespace std;
int n,k,a,t[500005];
signed main(){
IOS;TIE;
cin>>n>>k;
for(int i=1;i<=n;i++){
cin>>a;
t[a]++;
}
for(int i=1;i<=500000;i++){
t[i+1]+=t[i]/(i+1);
t[i]%=(i+1);
}
for(int i=1;i<k;i++){
if(t[i]){
cout<<"No"<<endl;
return 0;
}
}
cout<<"Yes"<<endl;
return 0;
}