当前位置: 首页 > news >正文

P1009 【深基4,例7】阶乘之和

#include <iostream>
using namespace std;
int main(){int n;cin>>n;long long ans=0;for(int i=1;i<=n;i++){long long factor=1;for(int j=1;j<=i;j++)factor=factor*j;ans=ans+factor;}cout<<ans<<endl;
}

这段代码的目的是计算从 1 到 n(包含 n)所有整数的阶乘之和。但是,随着 n 的增大,阶乘的值会迅速增长,很快就会超出 long long 类型的存储范围,导致溢出和错误的结果。比如:

当n的值超过21,就会出现溢出。

为了优化这个问题,我们可以考虑使用高精度计算库(如 GMP 或 C++17 引入的 <bit> 和 <numeric> 中的工具,尽管后者主要用于位操作和数值算法,并不直接支持大数运算),但在这里,我将展示一个更简单的优化方法:使用模运算来避免溢出(尽管这不会给出精确的阶乘和,但可以用于处理大数问题时的近似或特定场景下的计算)。

然而,对于直接计算阶乘和的问题,更实际的做法是使用一种算法来避免直接计算大数的阶乘,因为即使使用模运算,当 n 很大时,计算单个阶乘也会非常耗时。

不过,为了保持问题的简单性,并展示如何避免在 long long 范围内溢出,我们可以简单地限制 n 的大小,或者使用模运算来模拟一个“有限范围”的计算。但请注意,这不会给出原始问题的精确答案。

下面是一个使用模运算来避免溢出的示例代码(但请注意,这不会给出真实的阶乘和,只是演示如何避免溢出):

#include <iostream>
using namespace std;
const int MOD = 1e9 + 7; // 选择一个合适的模数来避免溢出  
int main(){int n;cin>>n;long long ans=0;for(int i=1;i<=n;i++){long long factor=1;for(int j=1;j<=i;j++)factor=factor*j%MOD;ans=(ans+factor)%MOD;}cout<<ans<<endl;
}

当n取21,50,结果没有溢出,如下:

选择 MOD=10 ^9 +7(即 1000000007)作为模数,在编程和算法竞赛中是一个常见的做法,其依据和优点主要包括以下几点:

  • 质数性质:10 ^9 +7 是一个质数。在模运算中,使用质数作为模数可以避免一些不必要的数学性质导致的错误。例如,如果模数不是质数,那么它可能有非平凡的因子,这可能会在某些算法中引入不必要的复杂性或错误。
  • 足够大:10 ^9 +7 是一个相对较大的质数,这意味着在大多数情况下,它可以避免在模运算过程中发生溢出之前,计算结果就已经达到了这个模数的上限。这对于处理大数问题特别有用,因为它允许我们在不牺牲太多精度的情况下,使用标准的整数类型(如 long long)进行计算。
  • 广泛应用:由于 10 ^9 +7 的这些优点,它已经被广泛应用于各种编程竞赛和算法实现中。因此,许多算法和数据结构库都内置了对这个模数的支持,或者至少提供了容易修改以使用这个模数的接口。
  • 避免负数:在某些情况下,模运算的结果可能是负数(特别是当被除数小于模数但为负数时)。然而,由于 10 ^9 +7 是一个大于所有标准整数类型能表示的最大负数的质数,因此在使用这个模数进行模运算时,我们几乎总是可以得到一个非负的结果(除非被除数是负数且绝对值非常大,但在实际应用中这种情况很少见)。
  • 习惯和传统:最后,选择 10 ^9 +7 作为模数也部分地基于习惯和传统。由于它在许多算法和竞赛中都被广泛使用,因此许多程序员和算法设计者都熟悉它,并倾向于在需要模运算时使用它。

但是,请注意,这种方法仍然非常低效,因为它对于每个 i 都重新计算了阶乘。在实际应用中,我们可以使用动态规划或其他数学技巧来更有效地计算阶乘和,特别是当 n 很大时。

#include <iostream>
using namespace std;
const int MOD = 1e9 + 7; // 选择一个合适的模数来避免溢出  
int main(){int n;cin>>n;long long ans=0,temp=1;for(int i=1;i<=n;i++){temp=temp*i%MOD;ans=(ans+temp)%MOD;}cout<<ans;
}

对于非常大的 n,直接计算阶乘和是不切实际的,你可能需要考虑使用近似方法或查找表等策略。如果问题允许,也可以考虑使用高精度计算库来处理大数。


http://www.mrgr.cn/news/14048.html

相关文章:

  • Java对象属性比较工具类(可用)
  • 【中秋特惠】南卡Runner Pro5:送给家人的科技健康礼!
  • 不用async与await将异步函数改为同步函数
  • 【递归回溯之floodfill算法专题练习】
  • 了解CSS中的BFC
  • 华为设备默认密码
  • Lombok组件的使用
  • E29.【C语言】练习:sizeof和strlen的习题集(A)
  • matlab 将数组从左向右翻转
  • 电子电气架构 --- 车载网简史(上)
  • 迷雾大陆辅助:VMOS云手机助力升级装备系统秘籍!
  • Python——xml.etree.ElementTree
  • SQL 注入之 sqlmap 实战
  • (二)、软硬件全开源智能手表,可全面高精度采集生命体征数据,进行健康检测。(HealthyPi Move)
  • 使用Python将应用程序添加进Linux/Windows/MacOS登录项
  • 异或+与+或
  • JavaWeb学习——原理篇学习
  • WHAT - 通过 react-use 源码学习 React(UI 篇)
  • 新华三H3C HCL配置IS-IS基本配置
  • 揭秘无线领夹麦克风五大行业隐秘:音质失真、隐私泄露需警惕!