【题解】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;
}
posted @ 2022-11-02 10:04  Binary_Lee  阅读(41)  评论(0)    收藏  举报
Title