阶乘和的关系

题目链接


题目大意:

    给定n个正整数和一个数k,问这n个数的阶乘之和能不能被k的阶乘整除,既:(a[1]!+a[2]!+a[3]!+....+a[n]!)  %  k!  ==  0。

题目分析:

  对于一个连续的阶乘我们可以对其进行合并。如:

  3*2!+ 3*3! = 3!+3*3! = 4*3! = 4!

  那么我们可以进行低位阶乘转化为高位阶乘,即  

for (int i = 1; i <= n; i++) {
//		while (a[i] > i) { //也可以这样写 
//			a[i + 1] ++;
//			a[i] = a[i] - (i + 1);
//		}
		//将阶乘高阶化
		a[i + 1] += a[i] / (i + 1);
		a[i] %= (i + 1);
	}

 

根据数学加法关系,如果每一个加数都可以被x整除的话,那他们的和也一定可以被x整除,相反则不能被x整除(我也不知道怎么证明0^0)。那么我们就可以用一个长度为5e5+10是数组(或者桶)来存储阶乘数,对其进行阶乘升高化,然后在判断1——x-1出是否有数存在(即是否有不是x!的倍数的加法因子)。如果有就输出No,否则输出Yes。

#include<bits/stdc++.h>
#define int long long
using namespace std;

const int N = 5e5 + 10;

int a[N]; //存放阶乘个数

signed main() {
	int n, x;
	cin >> n >> x;
	for (int i = 1; i <= n; i ++) {
		int x;
		cin >> x;
		a[x] ++;
	}

	for (int i = 1; i <= n; i++) {
//		while (a[i] > i) { //也可以这样写 
//			a[i + 1] ++;
//			a[i] = a[i] - (i + 1);
//		}
		//将阶乘高阶化
		a[i + 1] += a[i] / (i + 1);
		a[i] %= (i + 1);
	}

	bool p = true; //根据加法法则,如果每一个加数都可以被x整除,那么他们的和也一定能被X整除 
	for (int i = 1; i < x; i++) {
		if (a[i]) {
			p = false; //存在未被整除的,其结果不能被整除 
			break;
		}
	}

	if (p) puts("Yes");
	else puts("No");



	return 0;

}

 

posted @ 2022-10-24 20:31  Luli&  阅读(164)  评论(0编辑  收藏  举报