阶乘和的关系
题目链接
题目大意:
给定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; }
没有什么能阻止我对知识的追求!!!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?